From ca0c11bd823f37f03cc8067cb182876827d5275a Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Tue, 12 Mar 2013 10:40:45 -0700 Subject: [PATCH] Use more types than just 'unsigned' in the linker. Still chipping away at the situation where every variable in the linker was of type 'unsigned'. This patch switches counts over to being size_t and adds an explicit type for init/fini function pointers and arrays of function pointers. Also improve logging from CallArray. Also remove trailing "\n"s from log messages. Change-Id: Ie036d2622caac50f4d29f0570888bb527661d77e --- linker/dlfcn.cpp | 4 +- linker/linker.cpp | 172 +++++++++++++++++++++--------------------- linker/linker.h | 53 +++++++------ linker/linker_debug.h | 12 +-- 4 files changed, 120 insertions(+), 121 deletions(-) diff --git a/linker/dlfcn.cpp b/linker/dlfcn.cpp index 0b38ec445..638164d68 100644 --- a/linker/dlfcn.cpp +++ b/linker/dlfcn.cpp @@ -215,7 +215,7 @@ soinfo libdl_info = { phdr: 0, phnum: 0, entry: 0, base: 0, size: 0, - unused: 0, dynamic: 0, unused2: 0, unused3: 0, + unused1: 0, dynamic: 0, unused2: 0, unused3: 0, next: 0, flags: FLAG_LINKED, @@ -238,7 +238,7 @@ soinfo libdl_info = { mips_symtabno: 0, mips_local_gotno: 0, mips_gotsym: 0, #endif - refcount: 0, + ref_count: 0, { l_addr: 0, l_name: 0, l_ld: 0, l_next: 0, l_prev: 0, }, constructors_called: false, load_bias: 0, diff --git a/linker/linker.cpp b/linker/linker.cpp index f96e34799..2f119e44a 100755 --- a/linker/linker.cpp +++ b/linker/linker.cpp @@ -174,13 +174,13 @@ extern "C" void __attribute__((noinline)) __attribute__((visibility("default"))) static r_debug _r_debug = {1, NULL, &rtld_db_dlactivity, RT_CONSISTENT, 0}; -static link_map* r_debug_tail = 0; +static link_map_t* r_debug_tail = 0; static pthread_mutex_t gDebugMutex = PTHREAD_MUTEX_INITIALIZER; static void insert_soinfo_into_debug_map(soinfo * info) { // Copy the necessary fields into the debug structure. - link_map* map = &(info->linkmap); + link_map_t* map = &(info->link_map); map->l_addr = info->base; map->l_name = (char*) info->name; map->l_ld = (uintptr_t)info->dynamic; @@ -203,7 +203,7 @@ static void insert_soinfo_into_debug_map(soinfo * info) { } static void remove_soinfo_from_debug_map(soinfo* info) { - link_map* map = &(info->linkmap); + link_map_t* map = &(info->link_map); if (r_debug_tail == map) { r_debug_tail = map->l_prev; @@ -315,7 +315,7 @@ static soinfo* soinfo_alloc(const char* name) { sonext->next = si; sonext = si; - TRACE("name %s: allocated soinfo @ %p\n", name, si); + TRACE("name %s: allocated soinfo @ %p", name, si); return si; } @@ -327,7 +327,7 @@ static void soinfo_free(soinfo* si) soinfo *prev = NULL, *trav; - TRACE("name %s: freeing soinfo @ %p\n", si->name, si); + TRACE("name %s: freeing soinfo @ %p", si->name, si); for (trav = solist; trav != NULL; trav = trav->next) { if (trav == si) @@ -425,8 +425,8 @@ dl_iterate_phdr(int (*cb)(dl_phdr_info *info, size_t size, void *data), int rv = 0; for (soinfo* si = solist; si != NULL; si = si->next) { dl_phdr_info dl_info; - dl_info.dlpi_addr = si->linkmap.l_addr; - dl_info.dlpi_name = si->linkmap.l_name; + dl_info.dlpi_addr = si->link_map.l_addr; + dl_info.dlpi_name = si->link_map.l_name; dl_info.dlpi_phdr = si->phdr; dl_info.dlpi_phnum = si->phnum; rv = cb(&dl_info, sizeof(dl_phdr_info), data); @@ -445,7 +445,7 @@ static Elf32_Sym* soinfo_elf_lookup(soinfo* si, unsigned hash, const char* name) const char* strtab = si->strtab; unsigned n; - TRACE_TYPE(LOOKUP, "SEARCH %s in %s@0x%08x %08x %d\n", + TRACE_TYPE(LOOKUP, "SEARCH %s in %s@0x%08x %08x %d", name, si->name, si->base, hash, hash % si->nbucket); n = hash % si->nbucket; @@ -461,7 +461,7 @@ static Elf32_Sym* soinfo_elf_lookup(soinfo* si, unsigned hash, const char* name) continue; } - TRACE_TYPE(LOOKUP, "FOUND %s in %s (%08x) %d\n", + TRACE_TYPE(LOOKUP, "FOUND %s in %s (%08x) %d", name, si->name, s->st_value, s->st_size); return s; } @@ -510,7 +510,7 @@ static Elf32_Sym* soinfo_do_lookup(soinfo* si, const char* name, soinfo** lsi, s */ if (!si->has_DT_SYMBOLIC) { - DEBUG("%s: looking up %s in executable %s\n", + DEBUG("%s: looking up %s in executable %s", si->name, name, somain->name); s = soinfo_elf_lookup(somain, elf_hash, name); if (s != NULL) { @@ -541,7 +541,7 @@ static Elf32_Sym* soinfo_do_lookup(soinfo* si, const char* name, soinfo** lsi, s */ if (si->has_DT_SYMBOLIC) { - DEBUG("%s: looking up %s in executable %s after local scope\n", + DEBUG("%s: looking up %s in executable %s after local scope", si->name, name, somain->name); s = soinfo_elf_lookup(somain, elf_hash, name); if (s != NULL) { @@ -562,7 +562,7 @@ static Elf32_Sym* soinfo_do_lookup(soinfo* si, const char* name, soinfo** lsi, s } for (int i = 0; needed[i] != NULL; i++) { - DEBUG("%s: looking up %s in %s\n", + DEBUG("%s: looking up %s in %s", si->name, name, needed[i]->name); s = soinfo_elf_lookup(needed[i], elf_hash, name); if (s != NULL) { @@ -574,7 +574,7 @@ static Elf32_Sym* soinfo_do_lookup(soinfo* si, const char* name, soinfo** lsi, s done: if (s != NULL) { TRACE_TYPE(LOOKUP, "si %s sym %s s->st_value = 0x%08x, " - "found in %s, base = 0x%08x, load bias = 0x%08x\n", + "found in %s, base = 0x%08x, load bias = 0x%08x", si->name, name, s->st_value, (*lsi)->name, (*lsi)->base, (*lsi)->load_bias); return s; @@ -619,7 +619,7 @@ Elf32_Sym* dlsym_linear_lookup(const char* name, soinfo** found, soinfo* start) } if (s != NULL) { - TRACE_TYPE(LOOKUP, "%s s->st_value = 0x%08x, found->base = 0x%08x\n", + TRACE_TYPE(LOOKUP, "%s s->st_value = 0x%08x, found->base = 0x%08x", name, s->st_value, (*found)->base); } @@ -658,7 +658,7 @@ static void dump(soinfo* si) { Elf32_Sym* s = si->symtab; for (unsigned n = 0; n < si->nchain; n++) { - TRACE("%04d> %08x: %02x %04x %08x %08x %s\n", n, s, + TRACE("%04d> %08x: %02x %04x %08x %08x %s", n, s, s->st_info, s->st_shndx, s->st_value, s->st_size, si->strtab + s->st_name); s++; @@ -671,7 +671,7 @@ static int open_library_on_path(const char* name, const char* const paths[]) { for (size_t i = 0; paths[i] != NULL; ++i) { int n = __libc_format_buffer(buf, sizeof(buf), "%s/%s", paths[i], name); if (n < 0 || n >= static_cast(sizeof(buf))) { - PRINT("Warning: ignoring very long library path: %s/%s\n", paths[i], name); + PRINT("Warning: ignoring very long library path: %s/%s", paths[i], name); continue; } int fd = TEMP_FAILURE_RETRY(open(buf, O_RDONLY | O_CLOEXEC)); @@ -683,7 +683,7 @@ static int open_library_on_path(const char* name, const char* const paths[]) { } static int open_library(const char* name) { - TRACE("[ opening %s ]\n", name); + TRACE("[ opening %s ]", name); // If the name contains a slash, we should attempt to open it directly and not search the paths. if (strchr(name, '/') != NULL) { @@ -765,7 +765,7 @@ static soinfo* find_library_internal(const char* name) { return NULL; } - TRACE("[ '%s' has not been loaded yet. Locating...]\n", name); + TRACE("[ '%s' has not been loaded yet. Locating...]", name); si = load_library(name); if (si == NULL) { return NULL; @@ -773,7 +773,7 @@ static soinfo* find_library_internal(const char* name) { // At this point we know that whatever is loaded @ base is a valid ELF // shared library whose segments are properly mapped in. - TRACE("[ init_library base=0x%08x sz=0x%08x name='%s') ]\n", + TRACE("[ init_library base=0x%08x sz=0x%08x name='%s' ]", si->base, si->size, si->name); if (!soinfo_link_image(si)) { @@ -788,14 +788,14 @@ static soinfo* find_library_internal(const char* name) { static soinfo* find_library(const char* name) { soinfo* si = find_library_internal(name); if (si != NULL) { - si->refcount++; + si->ref_count++; } return si; } static int soinfo_unload(soinfo* si) { - if (si->refcount == 1) { - TRACE("unloading '%s'\n", si->name); + if (si->ref_count == 1) { + TRACE("unloading '%s'", si->name); si->CallDestructors(); for (Elf32_Dyn* d = si->dynamic; d->d_tag != DT_NULL; ++d) { @@ -803,7 +803,7 @@ static int soinfo_unload(soinfo* si) { const char* library_name = si->strtab + d->d_un.d_val; soinfo* lsi = find_loaded_library(library_name); if (lsi != NULL) { - TRACE("%s needs to unload %s\n", si->name, lsi->name); + TRACE("%s needs to unload %s", si->name, lsi->name); soinfo_unload(lsi); } else { // TODO: should we return -1 in this case? @@ -815,10 +815,10 @@ static int soinfo_unload(soinfo* si) { munmap(reinterpret_cast(si->base), si->size); notify_gdb_of_unload(si); soinfo_free(si); - si->refcount = 0; + si->ref_count = 0; } else { - si->refcount--; - TRACE("not unloading '%s', decrementing refcount to %d\n", si->name, si->refcount); + si->ref_count--; + TRACE("not unloading '%s', decrementing ref_count to %d", si->name, si->ref_count); } return 0; } @@ -870,7 +870,7 @@ static int soinfo_relocate(soinfo* si, Elf32_Rel* rel, unsigned count, Elf32_Addr sym_addr = 0; char* sym_name = NULL; - DEBUG("Processing '%s' relocation at index %d\n", si->name, idx); + DEBUG("Processing '%s' relocation at index %d", si->name, idx); if (type == 0) { // R_*_NONE continue; } @@ -957,25 +957,25 @@ static int soinfo_relocate(soinfo* si, Elf32_Rel* rel, unsigned count, case R_ARM_JUMP_SLOT: count_relocation(kRelocAbsolute); MARK(rel->r_offset); - TRACE_TYPE(RELO, "RELO JMP_SLOT %08x <- %08x %s\n", reloc, sym_addr, sym_name); + TRACE_TYPE(RELO, "RELO JMP_SLOT %08x <- %08x %s", reloc, sym_addr, sym_name); *reinterpret_cast(reloc) = sym_addr; break; case R_ARM_GLOB_DAT: count_relocation(kRelocAbsolute); MARK(rel->r_offset); - TRACE_TYPE(RELO, "RELO GLOB_DAT %08x <- %08x %s\n", reloc, sym_addr, sym_name); + TRACE_TYPE(RELO, "RELO GLOB_DAT %08x <- %08x %s", reloc, sym_addr, sym_name); *reinterpret_cast(reloc) = sym_addr; break; case R_ARM_ABS32: count_relocation(kRelocAbsolute); MARK(rel->r_offset); - TRACE_TYPE(RELO, "RELO ABS %08x <- %08x %s\n", reloc, sym_addr, sym_name); + TRACE_TYPE(RELO, "RELO ABS %08x <- %08x %s", reloc, sym_addr, sym_name); *reinterpret_cast(reloc) += sym_addr; break; case R_ARM_REL32: count_relocation(kRelocRelative); MARK(rel->r_offset); - TRACE_TYPE(RELO, "RELO REL32 %08x <- %08x - %08x %s\n", + TRACE_TYPE(RELO, "RELO REL32 %08x <- %08x - %08x %s", reloc, sym_addr, rel->r_offset, sym_name); *reinterpret_cast(reloc) += sym_addr - rel->r_offset; break; @@ -983,20 +983,20 @@ static int soinfo_relocate(soinfo* si, Elf32_Rel* rel, unsigned count, case R_386_JMP_SLOT: count_relocation(kRelocAbsolute); MARK(rel->r_offset); - TRACE_TYPE(RELO, "RELO JMP_SLOT %08x <- %08x %s\n", reloc, sym_addr, sym_name); + TRACE_TYPE(RELO, "RELO JMP_SLOT %08x <- %08x %s", reloc, sym_addr, sym_name); *reinterpret_cast(reloc) = sym_addr; break; case R_386_GLOB_DAT: count_relocation(kRelocAbsolute); MARK(rel->r_offset); - TRACE_TYPE(RELO, "RELO GLOB_DAT %08x <- %08x %s\n", reloc, sym_addr, sym_name); + TRACE_TYPE(RELO, "RELO GLOB_DAT %08x <- %08x %s", reloc, sym_addr, sym_name); *reinterpret_cast(reloc) = sym_addr; break; #elif defined(ANDROID_MIPS_LINKER) case R_MIPS_REL32: count_relocation(kRelocAbsolute); MARK(rel->r_offset); - TRACE_TYPE(RELO, "RELO REL32 %08x <- %08x %s\n", + TRACE_TYPE(RELO, "RELO REL32 %08x <- %08x %s", reloc, sym_addr, (sym_name) ? sym_name : "*SECTIONHDR*"); if (s) { *reinterpret_cast(reloc) += sym_addr; @@ -1017,7 +1017,7 @@ static int soinfo_relocate(soinfo* si, Elf32_Rel* rel, unsigned count, DL_ERR("odd RELATIVE form..."); return -1; } - TRACE_TYPE(RELO, "RELO RELATIVE %08x <- +%08x\n", reloc, si->base); + TRACE_TYPE(RELO, "RELO RELATIVE %08x <- +%08x", reloc, si->base); *reinterpret_cast(reloc) += si->base; break; @@ -1026,14 +1026,14 @@ static int soinfo_relocate(soinfo* si, Elf32_Rel* rel, unsigned count, count_relocation(kRelocRelative); MARK(rel->r_offset); - TRACE_TYPE(RELO, "RELO R_386_32 %08x <- +%08x %s\n", reloc, sym_addr, sym_name); + TRACE_TYPE(RELO, "RELO R_386_32 %08x <- +%08x %s", reloc, sym_addr, sym_name); *reinterpret_cast(reloc) += sym_addr; break; case R_386_PC32: count_relocation(kRelocRelative); MARK(rel->r_offset); - TRACE_TYPE(RELO, "RELO R_386_PC32 %08x <- +%08x (%08x - %08x) %s\n", + TRACE_TYPE(RELO, "RELO R_386_PC32 %08x <- +%08x (%08x - %08x) %s", reloc, (sym_addr - reloc), sym_addr, reloc, sym_name); *reinterpret_cast(reloc) += (sym_addr - reloc); break; @@ -1058,7 +1058,7 @@ static int soinfo_relocate(soinfo* si, Elf32_Rel* rel, unsigned count, } count_relocation(kRelocCopy); MARK(rel->r_offset); - TRACE_TYPE(RELO, "RELO %08x <- %d @ %08x %s\n", reloc, s->st_size, sym_addr, sym_name); + TRACE_TYPE(RELO, "RELO %08x <- %d @ %08x %s", reloc, s->st_size, sym_addr, sym_name); if (reloc == sym_addr) { Elf32_Sym *src = soinfo_do_lookup(NULL, sym_name, &lsi, needed); @@ -1176,37 +1176,33 @@ static int mips_relocate_got(soinfo* si, soinfo* needed[]) { * * DT_FINI_ARRAY must be parsed in reverse order. */ -void soinfo::CallArray(const char* array_name UNUSED, unsigned* array, int count, bool reverse) { - if (array == NULL) { +void soinfo::CallArray(const char* array_name UNUSED, linker_function_t* functions, size_t count, bool reverse) { + if (functions == NULL) { return; } - int step = 1; - if (reverse) { - array += (count-1); - step = -1; + TRACE("[ Calling %s (size %d) @ %p for '%s' ]", array_name, count, functions, name); + + int begin = reverse ? (count - 1) : 0; + int end = reverse ? -1 : count; + int step = reverse ? -1 : 1; + + for (int i = begin; i != end; i += step) { + TRACE("[ %s[%d] == %p ]", array_name, i, functions[i]); + CallFunction("function", functions[i]); } - TRACE("[ Calling %s @ %p [%d] for '%s' ]\n", array_name, array, count, name); - - for (int n = count; n > 0; n--) { - TRACE("[ Looking at %s[%d] *%p == 0x%08x ]\n", array_name, n, array, *array); - void (*func)() = (void (*)()) *array; - array += step; - CallFunction("function", func); - } - - TRACE("[ Done calling %s for '%s' ]\n", array_name, name); + TRACE("[ Done calling %s for '%s' ]", array_name, name); } -void soinfo::CallFunction(const char* function_name UNUSED, void (*function)()) { +void soinfo::CallFunction(const char* function_name UNUSED, linker_function_t function) { if (function == NULL || reinterpret_cast(function) == static_cast(-1)) { return; } - TRACE("[ Calling %s @ %p for '%s' ]\n", function_name, function, name); + TRACE("[ Calling %s @ %p for '%s' ]", function_name, function, name); function(); - TRACE("[ Done calling %s for '%s' ]\n", function_name, name); + TRACE("[ Done calling %s @ %p for '%s' ]", function_name, function, name); // The function may have called dlopen(3) or dlclose(3), so we need to ensure our data structures // are still writable. This happens with our debug malloc (see http://b/7941716). @@ -1273,7 +1269,7 @@ static int nullify_closed_stdio() { DL_ERR("cannot open /dev/null: %s", strerror(errno)); return -1; } - TRACE("[ Opened /dev/null file-descriptor=%d]\n", dev_null); + TRACE("[ Opened /dev/null file-descriptor=%d]", dev_null); /* If any of the stdio file descriptors is valid and not associated with /dev/null, dup /dev/null to it. */ @@ -1283,7 +1279,7 @@ static int nullify_closed_stdio() { continue; } - TRACE("[ Nullifying stdio file descriptor %d]\n", i); + TRACE("[ Nullifying stdio file descriptor %d]", i); status = TEMP_FAILURE_RETRY(fcntl(i, F_GETFL)); /* If file is opened, we are good. */ @@ -1312,7 +1308,7 @@ static int nullify_closed_stdio() { /* If /dev/null is not one of the stdio file descriptors, close it. */ if (dev_null > 2) { - TRACE("[ Closing /dev/null file-descriptor=%d]\n", dev_null); + TRACE("[ Closing /dev/null file-descriptor=%d]", dev_null); status = TEMP_FAILURE_RETRY(close(dev_null)); if (status == -1) { DL_ERR("close failed: %s", strerror(errno)); @@ -1332,8 +1328,8 @@ static bool soinfo_link_image(soinfo* si) { /* We can't debug anything until the linker is relocated */ if (!relocating_linker) { - INFO("[ linking %s ]\n", si->name); - DEBUG("si->base = 0x%08x si->flags = 0x%08x\n", si->base, si->flags); + INFO("[ linking %s ]", si->name); + DEBUG("si->base = 0x%08x si->flags = 0x%08x", si->base, si->flags); } /* Extract dynamic section */ @@ -1348,7 +1344,7 @@ static bool soinfo_link_image(soinfo* si) { return false; } else { if (!relocating_linker) { - DEBUG("dynamic = %p\n", si->dynamic); + DEBUG("dynamic = %p", si->dynamic); } } @@ -1360,7 +1356,7 @@ static bool soinfo_link_image(soinfo* si) { /* extract useful information from dynamic section */ uint32_t needed_count = 0; for (Elf32_Dyn* d = si->dynamic; d->d_tag != DT_NULL; ++d) { - DEBUG("d = %p, d[0](tag) = 0x%08x d[1](val) = 0x%08x\n", d, d->d_tag, d->d_un.d_val); + DEBUG("d = %p, d[0](tag) = 0x%08x d[1](val) = 0x%08x", d, d->d_tag, d->d_un.d_val); switch(d->d_tag){ case DT_HASH: si->nbucket = ((unsigned *) (base + d->d_un.d_ptr))[0]; @@ -1407,30 +1403,30 @@ static bool soinfo_link_image(soinfo* si) { DL_ERR("unsupported DT_RELA in \"%s\"", si->name); return false; case DT_INIT: - si->init_func = (void (*)(void))(base + d->d_un.d_ptr); - DEBUG("%s constructors (init func) found at %p\n", si->name, si->init_func); + si->init_func = reinterpret_cast(base + d->d_un.d_ptr); + DEBUG("%s constructors (init func) found at %p", si->name, si->init_func); break; case DT_FINI: - si->fini_func = (void (*)(void))(base + d->d_un.d_ptr); - DEBUG("%s destructors (fini func) found at %p\n", si->name, si->fini_func); + si->fini_func = reinterpret_cast(base + d->d_un.d_ptr); + DEBUG("%s destructors (fini func) found at %p", si->name, si->fini_func); break; case DT_INIT_ARRAY: - si->init_array = (unsigned *)(base + d->d_un.d_ptr); - DEBUG("%s constructors (init_array) found at %p\n", si->name, si->init_array); + si->init_array = reinterpret_cast(base + d->d_un.d_ptr); + DEBUG("%s constructors (init_array) found at %p", si->name, si->init_array); break; case DT_INIT_ARRAYSZ: si->init_array_count = ((unsigned)d->d_un.d_val) / sizeof(Elf32_Addr); break; case DT_FINI_ARRAY: - si->fini_array = (unsigned *)(base + d->d_un.d_ptr); - DEBUG("%s destructors (fini_array) found at %p\n", si->name, si->fini_array); + si->fini_array = reinterpret_cast(base + d->d_un.d_ptr); + DEBUG("%s destructors (fini_array) found at %p", si->name, si->fini_array); break; case DT_FINI_ARRAYSZ: si->fini_array_count = ((unsigned)d->d_un.d_val) / sizeof(Elf32_Addr); break; case DT_PREINIT_ARRAY: - si->preinit_array = (unsigned *)(base + d->d_un.d_ptr); - DEBUG("%s constructors (preinit_array) found at %p\n", si->name, si->preinit_array); + si->preinit_array = reinterpret_cast(base + d->d_un.d_ptr); + DEBUG("%s constructors (preinit_array) found at %p", si->name, si->preinit_array); break; case DT_PREINIT_ARRAYSZ: si->preinit_array_count = ((unsigned)d->d_un.d_val) / sizeof(Elf32_Addr); @@ -1486,13 +1482,13 @@ static bool soinfo_link_image(soinfo* si) { break; default: - DEBUG("Unused DT entry: type 0x%08x arg 0x%08x\n", d->d_tag, d->d_un.d_val); + DEBUG("Unused DT entry: type 0x%08x arg 0x%08x", d->d_tag, d->d_un.d_val); break; #endif } } - DEBUG("si->base = 0x%08x, si->strtab = %p, si->symtab = %p\n", + DEBUG("si->base = 0x%08x, si->strtab = %p, si->symtab = %p", si->base, si->strtab, si->symtab); // Sanity checks. @@ -1534,7 +1530,7 @@ static bool soinfo_link_image(soinfo* si) { for (Elf32_Dyn* d = si->dynamic; d->d_tag != DT_NULL; ++d) { if (d->d_tag == DT_NEEDED) { const char* library_name = si->strtab + d->d_un.d_val; - DEBUG("%s needs %s\n", si->name, library_name); + DEBUG("%s needs %s", si->name, library_name); soinfo* lsi = find_library(library_name); if (lsi == NULL) { strlcpy(tmp_err_buf, linker_get_error_buffer(), sizeof(tmp_err_buf)); @@ -1561,13 +1557,13 @@ static bool soinfo_link_image(soinfo* si) { } if (si->plt_rel != NULL) { - DEBUG("[ relocating %s plt ]\n", si->name ); + DEBUG("[ relocating %s plt ]", si->name ); if (soinfo_relocate(si, si->plt_rel, si->plt_rel_count, needed)) { return false; } } if (si->rel != NULL) { - DEBUG("[ relocating %s ]\n", si->name ); + DEBUG("[ relocating %s ]", si->name ); if (soinfo_relocate(si, si->rel, si->rel_count, needed)) { return false; } @@ -1580,7 +1576,7 @@ static bool soinfo_link_image(soinfo* si) { #endif si->flags |= FLAG_LINKED; - DEBUG("[ finished linking %s ]\n", si->name); + DEBUG("[ finished linking %s ]", si->name); if (si->has_text_relocations) { /* All relocations are done, we can protect our segments back to @@ -1649,7 +1645,7 @@ static Elf32_Addr __linker_init_post_relocation(KernelArgumentBlock& args, Elf32 ldpreload_env = linker_env_get("LD_PRELOAD"); } - INFO("[ android linker & debugger ]\n"); + INFO("[ android linker & debugger ]"); soinfo* si = soinfo_alloc(args.argv[0]); if (si == NULL) { @@ -1658,7 +1654,7 @@ static Elf32_Addr __linker_init_post_relocation(KernelArgumentBlock& args, Elf32 /* bootstrap the link map, the main exe always needs to be first */ si->flags |= FLAG_EXE; - link_map* map = &(si->linkmap); + link_map_t* map = &(si->link_map); map->l_addr = 0; map->l_name = args.argv[0]; @@ -1706,7 +1702,7 @@ static Elf32_Addr __linker_init_post_relocation(KernelArgumentBlock& args, Elf32 si->base = 0; si->size = phdr_table_get_load_size(si->phdr, si->phnum); si->load_bias = 0; - for (int i = 0; i < si->phnum; ++i) { + for (size_t i = 0; i < si->phnum; ++i) { if (si->phdr[i].p_type == PT_PHDR) { si->load_bias = reinterpret_cast(si->phdr) - si->phdr[i].p_vaddr; si->base = reinterpret_cast(si->phdr) - si->phdr[i].p_offset; @@ -1714,7 +1710,7 @@ static Elf32_Addr __linker_init_post_relocation(KernelArgumentBlock& args, Elf32 } } si->dynamic = NULL; - si->refcount = 1; + si->ref_count = 1; // Use LD_LIBRARY_PATH and LD_PRELOAD (but only if we aren't setuid/setgid). parse_LD_LIBRARY_PATH(ldpath_env); @@ -1743,13 +1739,13 @@ static Elf32_Addr __linker_init_post_relocation(KernelArgumentBlock& args, Elf32 #if TIMING gettimeofday(&t1,NULL); - PRINT("LINKER TIME: %s: %d microseconds\n", args.argv[0], (int) ( + PRINT("LINKER TIME: %s: %d microseconds", args.argv[0], (int) ( (((long long)t1.tv_sec * 1000000LL) + (long long)t1.tv_usec) - (((long long)t0.tv_sec * 1000000LL) + (long long)t0.tv_usec) )); #endif #if STATS - PRINT("RELO STATS: %s: %d abs, %d rel, %d copy, %d symbol\n", args.argv[0], + PRINT("RELO STATS: %s: %d abs, %d rel, %d copy, %d symbol", args.argv[0], linker_stats.count[kRelocAbsolute], linker_stats.count[kRelocRelative], linker_stats.count[kRelocCopy], @@ -1771,7 +1767,7 @@ static Elf32_Addr __linker_init_post_relocation(KernelArgumentBlock& args, Elf32 } } } - PRINT("PAGES MODIFIED: %s: %d (%dKB)\n", args.argv[0], count, count * 4); + PRINT("PAGES MODIFIED: %s: %d (%dKB)", args.argv[0], count, count * 4); } #endif @@ -1779,7 +1775,7 @@ static Elf32_Addr __linker_init_post_relocation(KernelArgumentBlock& args, Elf32 fflush(stdout); #endif - TRACE("[ Ready to execute '%s' @ 0x%08x ]\n", si->name, si->entry); + TRACE("[ Ready to execute '%s' @ 0x%08x ]", si->name, si->entry); return si->entry; } diff --git a/linker/linker.h b/linker/linker.h index a9ed11626..d6a4fc502 100644 --- a/linker/linker.h +++ b/linker/linker.h @@ -57,12 +57,12 @@ // Magic shared structures that GDB knows about. -struct link_map { +struct link_map_t { uintptr_t l_addr; char* l_name; uintptr_t l_ld; - struct link_map* l_next; - struct link_map* l_prev; + link_map_t* l_next; + link_map_t* l_prev; }; // Values for r_debug->state @@ -74,7 +74,7 @@ enum { struct r_debug { int32_t r_version; - struct link_map* r_map; + link_map_t* r_map; void (*r_brk)(void); int32_t r_state; uintptr_t r_ldbase; @@ -86,20 +86,23 @@ struct r_debug { #define SOINFO_NAME_LEN 128 +typedef void (*linker_function_t)(); + struct soinfo { + public: char name[SOINFO_NAME_LEN]; const Elf32_Phdr* phdr; - int phnum; + size_t phnum; Elf32_Addr entry; Elf32_Addr base; unsigned size; - int unused; // DO NOT USE, maintained for compatibility. + uint32_t unused1; // DO NOT USE, maintained for compatibility. Elf32_Dyn* dynamic; - unsigned unused2; // DO NOT USE, maintained for compatibility - unsigned unused3; // DO NOT USE, maintained for compatibility + uint32_t unused2; // DO NOT USE, maintained for compatibility + uint32_t unused3; // DO NOT USE, maintained for compatibility soinfo* next; unsigned flags; @@ -107,42 +110,42 @@ struct soinfo { const char* strtab; Elf32_Sym* symtab; - unsigned nbucket; - unsigned nchain; + size_t nbucket; + size_t nchain; unsigned* bucket; unsigned* chain; unsigned* plt_got; Elf32_Rel* plt_rel; - unsigned plt_rel_count; + size_t plt_rel_count; Elf32_Rel* rel; - unsigned rel_count; + size_t rel_count; - unsigned* preinit_array; - unsigned preinit_array_count; + linker_function_t* preinit_array; + size_t preinit_array_count; - unsigned* init_array; - unsigned init_array_count; - unsigned* fini_array; - unsigned fini_array_count; + linker_function_t* init_array; + size_t init_array_count; + linker_function_t* fini_array; + size_t fini_array_count; - void (*init_func)(); - void (*fini_func)(); + linker_function_t init_func; + linker_function_t fini_func; #if defined(ANDROID_ARM_LINKER) // ARM EABI section used for stack unwinding. unsigned* ARM_exidx; - unsigned ARM_exidx_count; + size_t ARM_exidx_count; #elif defined(ANDROID_MIPS_LINKER) unsigned mips_symtabno; unsigned mips_local_gotno; unsigned mips_gotsym; #endif - unsigned refcount; - struct link_map linkmap; + size_t ref_count; + link_map_t link_map; bool constructors_called; @@ -158,8 +161,8 @@ struct soinfo { void CallPreInitConstructors(); private: - void CallArray(const char* array_name, unsigned* array, int count, bool reverse); - void CallFunction(const char* function_name, void (*function)()); + void CallArray(const char* array_name, linker_function_t* functions, size_t count, bool reverse); + void CallFunction(const char* function_name, linker_function_t function); }; extern soinfo libdl_info; diff --git a/linker/linker_debug.h b/linker/linker_debug.h index 6aeb9ac1e..8fc235fbb 100644 --- a/linker/linker_debug.h +++ b/linker/linker_debug.h @@ -63,14 +63,14 @@ __LIBC_HIDDEN__ extern int gLdDebugVerbosity; #if LINKER_DEBUG_TO_LOG -#define _PRINTVF(v,x...) \ - do { \ - if (gLdDebugVerbosity > (v)) __libc_format_log(5-(v),"linker",x); \ +#define _PRINTVF(v,x...) \ + do { \ + if (gLdDebugVerbosity > (v)) __libc_format_log(5-(v),"linker",x); \ } while (0) #else /* !LINKER_DEBUG_TO_LOG */ -#define _PRINTVF(v,x...) \ - do { \ - if (gLdDebugVerbosity > (v)) __libc_format_fd(1, x); \ +#define _PRINTVF(v,x...) \ + do { \ + if (gLdDebugVerbosity > (v)) { __libc_format_fd(1, x); write(1, "\n", 1); } \ } while (0) #endif /* !LINKER_DEBUG_TO_LOG */