this repo has no description
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Fix stack trouble in TLS.cpp Start using Apple's libunwind

+170 -45
+1 -1
src/libdyld/MachOObject.cpp
··· 226 226 void* rv; 227 227 int flags = MAP_PRIVATE; 228 228 229 - if (strcmp(seg->segname, SEG_PAGEZERO) == 0 || seg->filesize == 0) 229 + if (strcmp(seg->segname, SEG_PAGEZERO) == 0 || seg->vmsize == 0) 230 230 continue; 231 231 232 232 assert(seg->vmsize >= seg->filesize);
+1
src/libdyld/MachOObject.h
··· 95 95 inline bool noRecursion() const { return m_noRecursion; } 96 96 97 97 std::vector<const char*> declaredDependencies() const { return m_file->dylibs(); } 98 + inline MachO* getMachOFile() const { return m_file; } 98 99 99 100 protected: 100 101 friend class DylibSearch;
+6 -6
src/libdyld/TLS.cpp
··· 27 27 #include "mutex.h" 28 28 29 29 extern "C" { 30 - int __darwin_pthread_key_create(pthread_key_t *key, void (*destructor)(void*)); 31 - int __darwin_pthread_key_delete(pthread_key_t key); 32 - int __darwin_pthread_setspecific(pthread_key_t key, const void *value); 30 + int __darwin_pthread_key_create(long *key, void (*destructor)(void*)); 31 + int __darwin_pthread_key_delete(long key); 32 + int __darwin_pthread_setspecific(long key, const void *value); 33 33 } 34 34 35 35 static void TLSRunDestructors(void* p); ··· 39 39 static Darling::Mutex m_imagesMutex; 40 40 41 41 // Used for a thread-local list of destructor-object pairs (DestructorLinkedListElement) 42 - static pthread_key_t m_keyDestructors; 42 + static long m_keyDestructors; 43 43 44 44 static void TLSSetupDestructors() 45 45 { ··· 69 69 void Darling::TLSSetup(void* imageKey, std::vector<tlv_descriptor*>& descriptors, std::vector<void*>& initializers, void* start, uintptr_t length) 70 70 { 71 71 Darling::MutexLock _l(&m_imagesMutex); 72 - pthread_key_t key; 72 + long key; 73 73 ImageData* id; 74 74 pthread_once_t once; 75 75 ··· 96 96 97 97 Darling::MutexLock _l(&m_imagesMutex); 98 98 auto it = m_images.find(imageKey); 99 - pthread_key_t key; 99 + long key; 100 100 101 101 if (it == m_images.end()) 102 102 return;
+1 -1
src/libdyld/TLS.h
··· 31 31 32 32 struct ImageData 33 33 { 34 - pthread_key_t key; 34 + long key; 35 35 36 36 // Location of initial variable values 37 37 void* start;
+160 -35
src/libdyld/dyld_public.cpp
··· 109 109 return module->path().c_str(); 110 110 } 111 111 112 - 113 - bool _dyld_find_unwind_sections(void* addr, struct dyld_unwind_sections* info) 114 - { 115 - #if 0 116 - TRACE1(addr); 117 - const FileMap::ImageMap* map = g_file_map.imageMapForAddr(addr); 118 - 119 - if (!map) // in ELF 120 - { 121 - memset(info, 0, sizeof(*info)); 122 - 123 - CBData data = { addr, info }; 124 - 125 - dl_iterate_phdr(dlCallback, &data); 126 - std::cout << "Dwarf section at " << info->dwarf_section << std::endl; 127 - return info->dwarf_section != 0; 128 - } 129 - else // in Mach-O 130 - { 131 - info->mh = map->header; 132 - info->dwarf_section = reinterpret_cast<const void*>(map->eh_frame.first + map->slide); 133 - info->dwarf_section_length = map->eh_frame.second; 134 - 135 - // FIXME: we would get "malformed __unwind_info" warnings otherwise 136 - // info->compact_unwind_section = reinterpret_cast<const void*>(map->unwind_info.first + map->slide); 137 - // info->compact_unwind_section_length = map->unwind_info.second; 138 - info->compact_unwind_section = 0; 139 - info->compact_unwind_section_length = 0; 140 - 141 - return true; 142 - } 143 - #endif 144 - return false; 145 - } 146 - 147 112 int32_t NSVersionOfRunTimeLibrary(const char* libraryName) 148 113 { 149 114 return -1; ··· 197 162 // glibc that we have forked. 198 163 } 199 164 165 + struct CBData 166 + { 167 + void* addr; 168 + struct dyld_unwind_sections* info; 169 + }; 170 + 171 + #pragma pack(1) 172 + struct eh_frame_hdr 173 + { 174 + uint8_t version, eh_frame_ptr_enc, fde_count_enc, table_enc; 175 + uint8_t eh_frame_ptr[]; 176 + }; 177 + #pragma pack() 178 + 179 + static uintptr_t readEncodedPointer(const eh_frame_hdr* hdr) 180 + { 181 + uint8_t format = hdr->eh_frame_ptr_enc & 0xf; 182 + uint8_t rel = hdr->eh_frame_ptr_enc & 0xf0; 183 + uintptr_t val; 184 + bool isSigned = false; 185 + 186 + if (hdr->eh_frame_ptr_enc == 0xff) 187 + return 0; 188 + 189 + switch (format) 190 + { 191 + case 1: // unsigned LEB 192 + { 193 + const uint8_t* ptr = reinterpret_cast<const uint8_t*>(hdr->eh_frame_ptr); 194 + val = uleb128(ptr); 195 + break; 196 + } 197 + case 2: // 2 bytes 198 + val = *reinterpret_cast<const uint16_t*>(hdr->eh_frame_ptr); 199 + break; 200 + case 3: 201 + val = *reinterpret_cast<const uint32_t*>(hdr->eh_frame_ptr); 202 + break; 203 + case 4: 204 + val = *reinterpret_cast<const uint64_t*>(hdr->eh_frame_ptr); 205 + break; 206 + case 9: // signed LEB 207 + { 208 + const uint8_t* ptr = reinterpret_cast<const uint8_t*>(hdr->eh_frame_ptr); 209 + val = sleb128(ptr); 210 + break; 211 + } 212 + // FIXME: add 'dlpi_addr' (base address) to these? 213 + case 0xa: 214 + val = *reinterpret_cast<const int16_t*>(hdr->eh_frame_ptr); 215 + break; 216 + case 0xb: 217 + val = *reinterpret_cast<const int32_t*>(hdr->eh_frame_ptr); 218 + break; 219 + case 0xc: 220 + val = *reinterpret_cast<const int64_t*>(hdr->eh_frame_ptr); 221 + break; 222 + default: 223 + return 0; 224 + } 225 + 226 + switch (rel) 227 + { 228 + case 0: // no change 229 + break; 230 + case 0x10: // pcrel 231 + val += reinterpret_cast<uintptr_t>(hdr) + 4; 232 + break; 233 + case 0x30: // eh_frame_hdr rel 234 + val += reinterpret_cast<uintptr_t>(hdr); 235 + break; 236 + default: 237 + return 0; 238 + } 239 + 240 + return val; 241 + } 242 + 243 + static int dlCallback(struct dl_phdr_info *info, size_t size, void *data) 244 + { 245 + CBData* cbdata = static_cast<CBData*>(data); 246 + bool addrMatch = false; 247 + void* maxAddr = 0; 248 + const eh_frame_hdr* ehdr = 0; 249 + 250 + if (cbdata->info->dwarf_section) // we already have a match 251 + return 0; 252 + 253 + //std::cout << "Looking into " << info->dlpi_name << std::endl; 254 + 255 + if (size < offsetof(struct dl_phdr_info, dlpi_phnum)) 256 + return 0; 257 + 258 + for (int i = 0; i < info->dlpi_phnum; i++) 259 + { 260 + const ElfW(Phdr)* phdr = &info->dlpi_phdr[i]; 261 + 262 + if (phdr->p_type == PT_LOAD) 263 + { 264 + void* from = reinterpret_cast<void*>(uintptr_t(info->dlpi_addr) + uintptr_t(phdr->p_vaddr)); 265 + void* to = reinterpret_cast<char*>(from) + phdr->p_memsz; 266 + 267 + if (cbdata->addr >= from && cbdata->addr < to) 268 + addrMatch = true; 269 + if (to > maxAddr) 270 + maxAddr = to; // TODO: could this be improved? libunwind does the same 271 + } 272 + else if (phdr->p_type == PT_GNU_EH_FRAME) 273 + { 274 + //std::cout << "Found .eh_frame_hdr in " << info->dlpi_name << std::endl; 275 + ehdr = reinterpret_cast<eh_frame_hdr*>(uintptr_t(info->dlpi_addr) + phdr->p_vaddr); 276 + // cbdata->info->dwarf_section_length = phdr->p_memsz; 277 + } 278 + } 279 + 280 + if (addrMatch && ehdr) 281 + { 282 + //std::cout << "*** Match found! " << info->dlpi_name << std::endl; 283 + 284 + // Now we find .eh_frame from .eh_frame_hdr 285 + if (ehdr->version != 1) 286 + return 0; 287 + cbdata->info->dwarf_section = reinterpret_cast<void*>(readEncodedPointer(ehdr)); 288 + cbdata->info->dwarf_section_length = uintptr_t(maxAddr) - uintptr_t(cbdata->info->dwarf_section); 289 + } 290 + 291 + return 0; 292 + } 293 + 294 + bool _dyld_find_unwind_sections(void* addr, struct dyld_unwind_sections* info) 295 + { 296 + TRACE1(addr); 297 + MachOObject* module = MachOMgr::instance()->objectForAddress((void*) addr); 298 + 299 + if (!module) // try ELF 300 + { 301 + memset(info, 0, sizeof(*info)); 302 + 303 + CBData data = { addr, info }; 304 + 305 + dl_iterate_phdr(dlCallback, &data); 306 + // std::cout << "Dwarf section at " << info->dwarf_section << std::endl; 307 + return info->dwarf_section != 0; 308 + } 309 + else // in Mach-O 310 + { 311 + info->mh = (const struct mach_header *) module->baseAddress(); 312 + info->dwarf_section = reinterpret_cast<const void*>(module->getMachOFile()->get_eh_frame().first + module->slide()); 313 + info->dwarf_section_length = module->getMachOFile()->get_eh_frame().second; 314 + 315 + // FIXME: we would get "malformed __unwind_info" warnings otherwise 316 + info->compact_unwind_section = reinterpret_cast<const void*>(module->getMachOFile()->get_unwind_info().first + module->slide()); 317 + info->compact_unwind_section_length = module->getMachOFile()->get_unwind_info().second; 318 + //info->compact_unwind_section = 0; 319 + //info->compact_unwind_section_length = 0; 320 + 321 + return true; 322 + } 323 + } 324 +
+1 -2
src/libsystem/CMakeLists.txt
··· 40 40 target_link_libraries(system PRIVATE dyld) 41 41 target_link_libraries(system PUBLIC system_malloc system_c system_kernel keymgr 42 42 system_m system_info system_notify libdispatch_shared objc launch 43 - removefile system_copyfile) 44 - # FIXME: unwind is removed until it receives EH sections from ELFs too 43 + removefile system_copyfile unwind) 45 44 46 45 install(TARGETS system DESTINATION lib${SUFFIX}/darling) 47 46