From 95f7a657a099c844a644b8736bd18e08afd50661 Mon Sep 17 00:00:00 2001 From: Nick Bowler Date: Mon, 14 May 2012 17:47:14 -0400 Subject: [PATCH] libupkg: Store export parent pointers directly. Making users handle the package member directly leads to some fairly ridiculous and somewhat tricky code. Resolve them all at package load time and store pointers directly in the upkg_export structure, which should help simplify the callers. At this point, we codify the "exports cannot have packages which are imports" assumption, which appears to be valid. It's not obvious how name lookup could possibly succeed if this were not the case. --- src/libupkg.c | 27 ++++++++++++++++++--------- src/upkg.c | 18 ++++++++++++------ src/upkg.h | 4 ++-- 3 files changed, 32 insertions(+), 17 deletions(-) diff --git a/src/libupkg.c b/src/libupkg.c index 5a9dce7..307e1be 100644 --- a/src/libupkg.c +++ b/src/libupkg.c @@ -276,6 +276,7 @@ static int pkg_init_exports(struct upkg_priv *pkg) while (index < pkg->pub.export_count) { struct upkg_export_priv *export = &pkg->exports[index]; + unsigned long parent_index; long tmp; /* Read some data into buffer. */ @@ -296,9 +297,17 @@ static int pkg_init_exports(struct upkg_priv *pkg) len += rc; if (nbuf-len < 4) goto err; - export->pub.package = unpack_s32_le(buf+len); + parent_index = unpack_32_le(buf+len); len += 4; + export->pub.parent = NULL; + if (parent_index > 0) { + parent_index--; + if (parent_index >= pkg->pub.export_count) + goto err; + export->pub.parent = &pkg->exports[parent_index].pub; + } + rc = upkg_decode_index(&tmp, buf+len, nbuf-len); if (rc == 0 || tmp < 0 || tmp >= pkg->pub.name_count) goto err; export->pub.name = pkg->names[tmp].name; @@ -488,22 +497,22 @@ const char *upkg_get_name(struct upkg *pub, unsigned long idx) return pkg->names[idx].name; } -long upkg_export_find(struct upkg *pub, long parent, const char *name) +long upkg_export_find(struct upkg *pub, long parent_index, const char *name) { struct upkg_priv *pkg = (struct upkg_priv *)pub; + struct upkg_export *parent = NULL; - /* This only makes sense if the assertion below is not violated. */ - long package = parent < 0 ? 0 : parent + 1; + if (parent_index >= 0) { + if (parent_index >= pkg->pub.export_count) + return -1; + parent = &pkg->exports[parent_index].pub; + } for (unsigned long i = 0; i < pkg->pub.export_count; i++) { struct upkg_export_priv *e = &pkg->exports[i]; - /* Assertion: an object's package is an export. */ - format_assert(e->pub.package >= 0, continue); - if (e->pub.package == package - && strcmp(e->pub.name, name) == 0) { + if (e->pub.parent == parent && !strcmp(e->pub.name, name)) return i; - } } return -1; diff --git a/src/upkg.c b/src/upkg.c index 8fe9a2a..e174c21 100644 --- a/src/upkg.c +++ b/src/upkg.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -228,7 +229,7 @@ int package_info(struct upkg *pkg) static void export_print_name(struct upkg *upkg, const struct upkg_export *e) { if (e) { - export_print_name(upkg, upkg_get_export(upkg, e->package-1)); + export_print_name(upkg, e->parent); printf(".%s", e->name); } } @@ -240,15 +241,20 @@ export_print_fullname(GTypeModule *pkg, const struct upkg_export *export) export_print_name(U_PKG(pkg)->pkg, export); } -static int package_list(GTypeModule *pkg, long parent) +static int package_list(GTypeModule *pkg, long current) { struct upkg *upkg = U_PKG(pkg)->pkg; - const struct upkg_export *export; + const struct upkg_export *parent = NULL; + + if (current >= 0) { + parent = upkg_get_export(upkg, current); + assert(parent != NULL); + } for (unsigned i = 0; i < upkg->export_count; i++) { - export = upkg_get_export(upkg, i); + const struct upkg_export *export = upkg_get_export(upkg, i); - if (export->package != parent) + if (export->parent != parent) continue; export_print_fullname(pkg, export); @@ -496,7 +502,7 @@ static int process_object(int mode, const char *objname) ret = object_info(pkg, current); break; case MODE_LIST: - ret = package_list(pkg, current+1); + ret = package_list(pkg, current); break; case MODE_EXPORT: if (current < 0) diff --git a/src/upkg.h b/src/upkg.h index 34291b7..12104cb 100644 --- a/src/upkg.h +++ b/src/upkg.h @@ -78,10 +78,10 @@ struct upkg { }; struct upkg_export { - const char *name; + const struct upkg_export *parent; + const char *name; unsigned long flags; - long package; }; struct upkg_file { -- 2.43.0