]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - android-sdk/platform-bionic.git/commitdiff
Fix unused DT entry warnings.
authorDmitriy Ivanov <dimitry@google.com>
Tue, 30 Sep 2014 02:14:45 +0000 (19:14 -0700)
committerDmitriy Ivanov <dimitry@google.com>
Tue, 30 Sep 2014 21:41:29 +0000 (14:41 -0700)
 DT_STRSZ Implement strtab boundary checks
 DT_FLAGS_1 Warn if flags other than DF_1_NOW|DF_1_GLOBAL are set

Bug: 17552334
Change-Id: Iaad29cd52f5b2d7d2f785fb351697906dc1617d9

libc/include/elf.h
linker/dlfcn.cpp
linker/linker.cpp
linker/linker.h

index 7a9485aea2aeba762e33e983a3aaa22688b78e37..7de464e0f5b2904016d032e98b0b4e6d9228ee48 100644 (file)
@@ -54,6 +54,35 @@ typedef struct {
 #define DF_BIND_NOW   0x00000008
 #define DF_STATIC_TLS 0x00000010
 
+#define DF_1_NOW        0x00000001 // Perform complete relocation processing.
+#define DF_1_GLOBAL     0x00000002 // implies RTLD_GLOBAL
+#define DF_1_GROUP      0x00000004
+#define DF_1_NODELETE   0x00000008 // implies RTLD_NODELETE
+#define DF_1_LOADFLTR   0x00000010
+#define DF_1_INITFIRST  0x00000020
+#define DF_1_NOOPEN     0x00000040 // Object can not be used with dlopen(3)
+#define DF_1_ORIGIN     0x00000080
+#define DF_1_DIRECT     0x00000100
+#define DF_1_TRANS      0x00000200
+#define DF_1_INTERPOSE  0x00000400
+#define DF_1_NODEFLIB   0x00000800
+#define DF_1_NODUMP     0x00001000 // Object cannot be dumped with dldump(3)
+#define DF_1_CONFALT    0x00002000
+#define DF_1_ENDFILTEE  0x00004000
+#define DF_1_DISPRELDNE 0x00008000
+#define DF_1_DISPRELPND 0x00010000
+#define DF_1_NODIRECT   0x00020000
+#define DF_1_IGNMULDEF  0x00040000 // Internal use
+#define DF_1_NOKSYMS    0x00080000 // Internal use
+#define DF_1_NOHDR      0x00100000 // Internal use
+#define DF_1_EDITED     0x00200000
+#define DF_1_NORELOC    0x00400000 // Internal use
+#define DF_1_SYMINTPOSE 0x00800000
+#define DF_1_GLOBAUDIT  0x01000000
+#define DF_1_SINGLETON  0x02000000
+#define DF_1_STUB       0x04000000
+#define DF_1_PIE        0x08000000
+
 #define DT_BIND_NOW 24
 #define DT_INIT_ARRAY 25
 #define DT_FINI_ARRAY 26
index c930ce985d794579f1087d138f00109162ce4260..98931c703c51e05dd0e0c3aed7b0ab5031805a22 100644 (file)
@@ -147,7 +147,7 @@ int dladdr(const void* addr, Dl_info* info) {
   // Determine if any symbol in the library contains the specified address.
   ElfW(Sym)* sym = dladdr_find_symbol(si, addr);
   if (sym != nullptr) {
-    info->dli_sname = si->strtab + sym->st_name;
+    info->dli_sname = si->get_string(sym->st_name);
     info->dli_saddr = reinterpret_cast<void*>(si->resolve_symbol_address(sym));
   }
 
@@ -245,6 +245,7 @@ soinfo* get_libdl_info() {
     __libdl_info.bucket = g_libdl_buckets;
     __libdl_info.chain = g_libdl_chains;
     __libdl_info.ref_count = 1;
+    __libdl_info.strtab_size = sizeof(ANDROID_LIBDL_STRTAB);
   }
 
   return &__libdl_info;
index 5b39668a9dcc0c251a3440d7c783abd3c19bcd1b..4f42c821592ee939d6983e0b46882baa3c4d0d53 100644 (file)
@@ -417,14 +417,13 @@ int dl_iterate_phdr(int (*cb)(dl_phdr_info* info, size_t size, void* data), void
 
 static ElfW(Sym)* soinfo_elf_lookup(soinfo* si, unsigned hash, const char* name) {
   ElfW(Sym)* symtab = si->symtab;
-  const char* strtab = si->strtab;
 
   TRACE_TYPE(LOOKUP, "SEARCH %s in %s@%p %x %zd",
              name, si->name, reinterpret_cast<void*>(si->base), hash, hash % si->nbucket);
 
   for (unsigned n = si->bucket[hash % si->nbucket]; n != 0; n = si->chain[n]) {
     ElfW(Sym)* s = symtab + n;
-    if (strcmp(strtab + s->st_name, name)) continue;
+    if (strcmp(si->get_string(s->st_name), name)) continue;
 
     // only concern ourselves with global and weak symbol definitions
     switch (ELF_ST_BIND(s->st_info)) {
@@ -775,7 +774,7 @@ template<typename F>
 static void for_each_dt_needed(const soinfo* si, F action) {
   for (ElfW(Dyn)* d = si->dynamic; d->d_tag != DT_NULL; ++d) {
     if (d->d_tag == DT_NEEDED) {
-      action(si->strtab + d->d_un.d_val);
+      action(si->get_string(d->d_un.d_val));
     }
   }
 }
@@ -1085,7 +1084,7 @@ int soinfo::Relocate(ElfW(Rela)* rela, unsigned count) {
     soinfo* lsi = nullptr;
 
     if (sym != 0) {
-      sym_name = reinterpret_cast<const char*>(strtab + symtab[sym].st_name);
+      sym_name = get_string(symtab[sym].st_name);
       s = soinfo_do_lookup(this, sym_name, &lsi);
       if (s == nullptr) {
         // We only allow an undefined symbol if this is a weak reference...
@@ -1363,7 +1362,7 @@ int soinfo::Relocate(ElfW(Rel)* rel, unsigned count) {
     soinfo* lsi = nullptr;
 
     if (sym != 0) {
-      sym_name = reinterpret_cast<const char*>(strtab + symtab[sym].st_name);
+      sym_name = get_string(symtab[sym].st_name);
       s = soinfo_do_lookup(this, sym_name, &lsi);
       if (s == nullptr) {
         // We only allow an undefined symbol if this is a weak reference...
@@ -1581,7 +1580,7 @@ static bool mips_relocate_got(soinfo* si) {
   got = si->plt_got + local_gotno;
   for (size_t g = gotsym; g < symtabno; g++, sym++, got++) {
     // This is an undefined reference... try to locate it.
-    const char* sym_name = si->strtab + sym->st_name;
+    const char* sym_name = si->get_string(sym->st_name);
     soinfo* lsi = nullptr;
     ElfW(Sym)* s = soinfo_do_lookup(si, sym_name, &lsi);
     if (s == nullptr) {
@@ -1787,6 +1786,14 @@ ElfW(Addr) soinfo::resolve_symbol_address(ElfW(Sym)* s) {
   return static_cast<ElfW(Addr)>(s->st_value + load_bias);
 }
 
+const char* soinfo::get_string(ElfW(Word) index) const {
+  if (has_min_version(1) && (index >= strtab_size)) {
+    __libc_fatal("%s: strtab out of bounds error; STRSZ=%zd, name=%d", name, strtab_size, index);
+  }
+
+  return strtab + index;
+}
+
 /* Force any of the closed stdin, stdout and stderr to be associated with
    /dev/null. */
 static int nullify_closed_stdio() {
@@ -1895,6 +1902,9 @@ bool soinfo::PrelinkImage() {
       case DT_STRTAB:
         strtab = reinterpret_cast<const char*>(load_bias + d->d_un.d_ptr);
         break;
+      case DT_STRSZ:
+        strtab_size = d->d_un.d_val;
+        break;
       case DT_SYMTAB:
         symtab = reinterpret_cast<ElfW(Sym)*>(load_bias + d->d_un.d_ptr);
         break;
@@ -2048,6 +2058,16 @@ bool soinfo::PrelinkImage() {
           has_DT_SYMBOLIC = true;
         }
         break;
+      case DT_FLAGS_1:
+        if ((d->d_un.d_val & DF_1_GLOBAL) != 0) {
+          rtld_flags |= RTLD_GLOBAL;
+        }
+        // TODO: Implement other flags
+
+        if ((d->d_un.d_val & ~(DF_1_NOW | DF_1_GLOBAL)) != 0) {
+          DL_WARN("Unsupported flags DT_FLAGS_1=%p", reinterpret_cast<void*>(d->d_un.d_val));
+        }
+        break;
 #if defined(__mips__)
       case DT_STRSZ:
         break;
@@ -2079,7 +2099,7 @@ bool soinfo::PrelinkImage() {
 
       default:
         if (!relocating_linker) {
-          DEBUG("%s: unused DT entry: type %p arg %p", name,
+          DL_WARN("%s: unused DT entry: type %p arg %p", name,
               reinterpret_cast<void*>(d->d_tag), reinterpret_cast<void*>(d->d_un.d_val));
         }
         break;
index 28969332d51ad732939d9289a9c30fad65406846..f6e3a48bad839ca11f2fe4f1de4d24d3503a8bfb 100644 (file)
@@ -136,7 +136,9 @@ struct soinfo {
   soinfo* next;
   unsigned flags;
 
+ private:
   const char* strtab;
+ public:
   ElfW(Sym)* symtab;
 
   size_t nbucket;
@@ -222,7 +224,9 @@ struct soinfo {
 
   ElfW(Addr) resolve_symbol_address(ElfW(Sym)* s);
 
-  bool inline has_min_version(uint32_t min_version) {
+  const char* get_string(ElfW(Word) index) const;
+
+  bool inline has_min_version(uint32_t min_version) const {
     return (flags & FLAG_NEW_SOINFO) != 0 && version >= min_version;
   }
  private:
@@ -249,6 +253,9 @@ struct soinfo {
 
   // version >= 1
   int rtld_flags;
+  size_t strtab_size;
+
+  friend soinfo* get_libdl_info();
 };
 
 extern soinfo* get_libdl_info();