1 /* 2 3 Copyright (C) 2000,2002,2004 Silicon Graphics, Inc. All Rights Reserved. 4 5 This program is free software; you can redistribute it and/or modify it 6 under the terms of version 2.1 of the GNU Lesser General Public License 7 as published by the Free Software Foundation. 8 9 This program is distributed in the hope that it would be useful, but 10 WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 13 Further, this software is distributed without any warranty that it is 14 free of the rightful claim of any third person regarding infringement 15 or the like. Any license provided herein, whether implied or 16 otherwise, applies only to this software file. Patent licenses, if 17 any, provided herein do not apply to combinations of this program with 18 other software, or any other product whatsoever. 19 20 You should have received a copy of the GNU Lesser General Public 21 License along with this program; if not, write the Free Software 22 Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 23 USA. 24 25 Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pky, 26 Mountain View, CA 94043, or: 27 28 http://www.sgi.com 29 30 For further information regarding this notice, see: 31 32 http://oss.sgi.com/projects/GenInfo/NoticeExplan 33 34 */ 35 36 37 38 #include "config.h" 39 #include "dwarf_incl.h" 40 #include <sys/types.h> 41 42 #include <stdlib.h> 43 #include <stdio.h> 44 #include <malloc.h> 45 46 /* 47 These files are included to get the sizes 48 of structs to set the ah_bytes_one_struct field 49 of the Dwarf_Alloc_Hdr_s structs for each 50 allocation type. 51 */ 52 #include "dwarf_line.h" 53 #include "dwarf_global.h" 54 #include "dwarf_arange.h" 55 #include "dwarf_abbrev.h" 56 #include "dwarf_die_deliv.h" 57 #include "dwarf_frame.h" 58 #include "dwarf_loc.h" 59 #include "dwarf_funcs.h" 60 #include "dwarf_types.h" 61 #include "dwarf_vars.h" 62 #include "dwarf_weaks.h" 63 64 static void _dwarf_free_special_error(Dwarf_Ptr space); 65 #ifdef DWARF_SIMPLE_MALLOC 66 static void _dwarf_simple_malloc_add_to_list(Dwarf_Debug dbg, 67 Dwarf_Ptr addr, 68 unsigned long size, 69 short alloc_type); 70 static void _dwarf_simple_malloc_delete_from_list(Dwarf_Debug dbg, 71 Dwarf_Ptr space, 72 short alloc_type); 73 void _dwarf_simple_malloc_botch(int err); 74 75 #endif /* DWARF_SIMPLE_MALLOC */ 76 77 78 79 80 /* 81 This macro adds the size of a pointer to the size of a 82 struct that is given to it. It rounds up the size to 83 be a multiple of the size of a pointer. This is done 84 so that every struct returned by _dwarf_get_alloc() 85 can be preceded by a pointer to the chunk it came from. 86 Before, it checks if the size of struct is less than 87 the size of a pointer. If yes, it returns the size 88 of 2 pointers. The returned size should be at least 89 the size of 2 pointers, since the first points to the 90 chunk the struct was allocated from, and the second 91 is used to link the free list. 92 93 If this is n32, we want the sizes to be 64-bit aligned 94 so that longlong in the structure we return to user 95 is aligned properly. Thus the _dw_fac of 2 96 97 Only long longs need to be properly aligned: we don't 98 have long double and don't align for that. 99 100 */ 101 #if _MIPS_SIM == _MIPS_SIM_NABI32 102 #define _DW_FAC 2 103 #define _DW_PS sizeof(void *) 104 #else 105 #define _DW_FAC 1 106 #define _DW_PS sizeof(void *) 107 #endif 108 #define _DW_RESERVE (_DW_FAC * _DW_PS) 109 110 /* Round size up to the next multiple of _DW_RESERVE bytes 111 */ 112 #define ROUND_SIZE(inputsize) \ 113 (((inputsize) % (_DW_RESERVE)) == 0 ? \ 114 (inputsize): \ 115 ((inputsize) + \ 116 (_DW_RESERVE) - ((inputsize) % (_DW_RESERVE)) )) 117 118 #define ROUND_SIZE_WITH_POINTER(i_size) (ROUND_SIZE(i_size) + _DW_RESERVE) 119 #define BASE_ALLOC 64 120 #define BIG_ALLOC 128 121 122 /* This translates into de_alloc_hdr index 123 ** the 0,1,1 entries are special: they don't use the 124 ** table values at all. 125 ** Rearranging the DW_DLA values would break binary compatibility 126 ** so that is not an option. 127 */ 128 struct ial_s { 129 int ia_al_num; /* Index into de_alloc_hdr table. */ 130 131 /* In bytes, one struct instance. This does not account for extra 132 space needed per block, but that (_DW_RESERVE) will be added in 133 later where it is needed (_DW_RESERVE space never added in 134 here). */ 135 int ia_struct_size; 136 137 138 /* Number of instances per alloc block. MUST be > 0. */ 139 int ia_base_count; 140 }; 141 142 static const 143 struct ial_s index_into_allocated[ALLOC_AREA_INDEX_TABLE_MAX] = { 144 {0, 1, 1}, /* none */ 145 {0, 1, 1,}, /* 1 DW_DLA_STRING */ 146 {1, sizeof(Dwarf_Loc), BASE_ALLOC} 147 , /* 2 DW_DLA_LOC */ 148 {2, sizeof(Dwarf_Locdesc), BASE_ALLOC} 149 , /* 3 DW_DLA_LOCDESC */ 150 {0, 1, 1} 151 , /* not used *//* 4 DW_DLA_ELLIST */ 152 {0, 1, 1} 153 , /* not used *//* 5 DW_DLA_BOUNDS */ 154 {3, sizeof(Dwarf_Block), BASE_ALLOC} 155 , /* 6 DW_DLA_BLOCK */ 156 {0, 1, 1} 157 , /* the actual dwarf_debug structure *//* 7 DW_DLA_DEBUG */ 158 {4, sizeof(struct Dwarf_Die_s), BIG_ALLOC}, /* 8 DW_DLA_DIE */ 159 {5, sizeof(struct Dwarf_Line_s), BIG_ALLOC}, /* 9 160 DW_DLA_LINE */ 161 {6, sizeof(struct Dwarf_Attribute_s), BIG_ALLOC * 2}, 162 /* 10 DW_DLA_ATTR */ 163 {0, 1, 1}, /* not used *//* 11 DW_DLA_TYPE */ 164 {0, 1, 1}, /* not used *//* 12 DW_DLA_SUBSCR */ 165 {7, sizeof(struct Dwarf_Global_s), BIG_ALLOC}, /* 13 166 DW_DLA_GLOBAL 167 */ 168 {8, sizeof(struct Dwarf_Error_s), BASE_ALLOC}, /* 14 169 DW_DLA_ERROR 170 */ 171 {0, 1, 1}, /* 15 DW_DLA_LIST */ 172 {0, 1, 1}, /* not used *//* 16 DW_DLA_LINEBUF */ 173 {9, sizeof(struct Dwarf_Arange_s), BASE_ALLOC}, /* 17 174 DW_DLA_ARANGE 175 */ 176 {10, sizeof(struct Dwarf_Abbrev_s), BIG_ALLOC}, /* 18 177 DW_DLA_ABBREV 178 */ 179 {11, sizeof(Dwarf_Frame_Op), BIG_ALLOC} 180 , /* 19 DW_DLA_FRAME_OP */ 181 {12, sizeof(struct Dwarf_Cie_s), BASE_ALLOC}, /* 20 182 DW_DLA_CIE */ 183 {13, sizeof(struct Dwarf_Fde_s), BASE_ALLOC}, /* 21 184 DW_DLA_FDE */ 185 {0, 1, 1}, /* 22 DW_DLA_LOC_BLOCK */ 186 {0, 1, 1}, /* 23 DW_DLA_FRAME_BLOCK */ 187 {14, sizeof(struct Dwarf_Global_s), BIG_ALLOC}, /* 24 188 DW_DLA_FUNC */ 189 {15, sizeof(struct Dwarf_Global_s), BIG_ALLOC}, /* 25 190 DW_DLA_TYPENAME 191 */ 192 {16, sizeof(struct Dwarf_Global_s), BIG_ALLOC}, /* 26 193 DW_DLA_VAR */ 194 {17, sizeof(struct Dwarf_Global_s), BASE_ALLOC}, /* 27 195 DW_DLA_WEAK */ 196 {0, 1, 1}, /* 28 DW_DLA_ADDR */ 197 {18, sizeof(struct Dwarf_Abbrev_List_s), BIG_ALLOC}, 198 /* 29 DW_DLA_ABBREV_LIST */ 199 {19, sizeof(struct Dwarf_Chain_s), BIG_ALLOC}, /* 30 200 DW_DLA_CHAIN 201 */ 202 {20, sizeof(struct Dwarf_CU_Context_s), BASE_ALLOC}, 203 /* 31 DW_DLA_CU_CONTEXT */ 204 {21, sizeof(struct Dwarf_Frame_s), BASE_ALLOC}, /* 32 205 DW_DLA_FRAME 206 */ 207 {22, sizeof(struct Dwarf_Global_Context_s), BASE_ALLOC}, 208 /* 33 DW_DLA_GLOBAL_CONTEXT */ 209 {23, sizeof(struct Dwarf_File_Entry_s), BASE_ALLOC}, 210 /* 34 DW_DLA_FILE_ENTRY */ 211 {24, sizeof(struct Dwarf_Line_Context_s), BASE_ALLOC}, 212 /* 35 DW_DLA_LINE_CONTEXT */ 213 {25, sizeof(struct Dwarf_Loc_Chain_s), BASE_ALLOC}, 214 /* 36 DW_DLA_LOC_CHAIN */ 215 {26, ABBREV_HASH_TABLE_SIZE * 2 * sizeof(Dwarf_Abbrev_List), 216 BASE_ALLOC} 217 , 218 /* 37 DW_DLA_HASH_TABLE */ 219 220 /* The following really use Global struct: used to be unique struct 221 per type, but now merged (11/99). The opaque types 222 are visible in the interface. The types are left in existence, 223 with unchanged numbers. 224 */ 225 {27, sizeof(struct Dwarf_Global_Context_s), BASE_ALLOC}, 226 /* 38 DW_DLA_FUNC_CONTEXT */ 227 {28, sizeof(struct Dwarf_Global_Context_s), BASE_ALLOC}, 228 /* 39 DW_DLA_TYPENAME_CONTEXT */ 229 {29, sizeof(struct Dwarf_Global_Context_s), BASE_ALLOC}, 230 /* 40 DW_DLA_VAR_CONTEXT */ 231 {30, sizeof(struct Dwarf_Global_Context_s), BASE_ALLOC}, 232 /* 41 DW_DLA_WEAK_CONTEXT */ 233 }; 234 235 #ifndef DWARF_SIMPLE_MALLOC 236 237 /* 238 This function is given a pointer to the header 239 structure that is used to allocate 1 struct of 240 the type given by alloc_type. It first checks 241 if a struct is available in its free list. If 242 not, it checks if 1 is available in its blob, 243 which is a chunk of memory that is reserved for 244 its use. If not, it malloc's a chunk. The 245 initial part of it is used to store the end 246 address of the chunk, and also to keep track 247 of the number of free structs in that chunk. 248 This information is used for freeing the chunk 249 when all the structs in it are free. 250 251 Assume all input arguments have been validated. 252 253 This function can be used only to allocate 1 254 struct of the given type. 255 256 It returns a pointer to the struct that the 257 user can use. It returns NULL only when it 258 is out of free structs, and cannot malloc 259 any more. The struct returned is zero-ed. 260 261 A pointer to the chunk that the struct belongs 262 to is stored in the bytes preceding the 263 returned address. Since this pointer it 264 never overwritten, when a struct is allocated 265 from the free_list this pointer does not 266 have to be written. In the 2 other cases, 267 where the struct is allocated from a new 268 chunk, or the blob, a pointer to the chunk 269 is written. 270 */ 271 static Dwarf_Ptr 272 _dwarf_find_memory(Dwarf_Alloc_Hdr alloc_hdr) 273 { 274 /* Pointer to the struct allocated. */ 275 Dwarf_Small *ret_mem = 0; 276 277 /* Pointer to info about chunks allocated. */ 278 Dwarf_Alloc_Area alloc_area; 279 280 /* Size of chunk malloc'ed when no free structs left. */ 281 Dwarf_Signed mem_block_size; 282 283 /* Pointer to block malloc'ed. */ 284 Dwarf_Small *mem_block; 285 286 /* 287 Check the alloc_area from which the last allocation was made 288 (most recent new block). If that is not successful, then 289 search the list of alloc_area's from alloc_header. */ 290 alloc_area = alloc_hdr->ah_last_alloc_area; 291 if (alloc_area == NULL || alloc_area->aa_free_structs_in_chunk == 0) 292 for (alloc_area = alloc_hdr->ah_alloc_area_head; 293 alloc_area != NULL; alloc_area = alloc_area->aa_next) { 294 295 if (alloc_area->aa_free_structs_in_chunk > 0) { 296 break; /* found a free entry! */ 297 } 298 299 } 300 301 if (alloc_area != NULL) { 302 alloc_area->aa_free_structs_in_chunk--; 303 304 if (alloc_area->aa_free_list != NULL) { 305 ret_mem = alloc_area->aa_free_list; 306 307 /* 308 Update the free list. The initial part of the struct is 309 used to hold a pointer to the next struct on the free 310 list. In this way, the free list chain is maintained at 311 0 memory cost. */ 312 alloc_area->aa_free_list = 313 ((Dwarf_Free_List) ret_mem)->fl_next; 314 } else if (alloc_area->aa_blob_start < alloc_area->aa_blob_end) { 315 ret_mem = alloc_area->aa_blob_start; 316 317 /* 318 Store pointer to chunk this struct belongs to in the 319 first few bytes. Return pointer to bytes after this 320 pointer storage. */ 321 *(Dwarf_Alloc_Area *) ret_mem = alloc_area; 322 ret_mem += _DW_RESERVE; 323 324 alloc_area->aa_blob_start += alloc_hdr->ah_bytes_one_struct; 325 } else { 326 /* else fall thru , though it should be impossible to fall 327 thru. And represents a disastrous programming error if 328 we get here. */ 329 #ifdef DEBUG 330 fprintf(stderr, "libdwarf Internal error start %x end %x\n", 331 (int) alloc_area->aa_blob_start, 332 (int) alloc_area->aa_blob_end); 333 #endif 334 } 335 } 336 337 /* New memory has to malloc'ed since there are no free structs. */ 338 if (ret_mem == 0) { 339 Dwarf_Word rounded_area_hdr_size; 340 341 alloc_hdr->ah_chunks_allocated++; 342 343 { /* this nonsense avoids a warning */ 344 /* CONSTCOND would be better */ 345 unsigned long v = sizeof(struct Dwarf_Alloc_Area_s); 346 347 rounded_area_hdr_size = ROUND_SIZE(v); 348 } 349 350 /* 351 Allocate memory to contain the required number of structs 352 and the Dwarf_Alloc_Area_s to control it. */ 353 mem_block_size = alloc_hdr->ah_bytes_malloc_per_chunk + 354 rounded_area_hdr_size; 355 356 mem_block = malloc(mem_block_size); 357 if (mem_block == NULL) { 358 return (NULL); 359 } 360 361 362 /* 363 Attach the Dwarf_Alloc_Area_s struct to the list of chunks 364 malloc'ed for this struct type. Also initialize the fields 365 of the Dwarf_Alloc_Area_s. */ 366 alloc_area = (Dwarf_Alloc_Area) mem_block; 367 alloc_area->aa_prev = 0; 368 if (alloc_hdr->ah_alloc_area_head != NULL) { 369 alloc_hdr->ah_alloc_area_head->aa_prev = alloc_area; 370 } 371 alloc_area->aa_free_list = 0; 372 alloc_area->aa_next = alloc_hdr->ah_alloc_area_head; 373 alloc_hdr->ah_alloc_area_head = alloc_area; 374 375 alloc_area->aa_alloc_hdr = alloc_hdr; 376 alloc_area->aa_free_structs_in_chunk = 377 (Dwarf_Sword) alloc_hdr->ah_structs_per_chunk - 1; 378 if (alloc_area->aa_free_structs_in_chunk < 1) { 379 /* If we get here, there is a disastrous programming error 380 somewhere. */ 381 #ifdef DEBUG 382 fprintf(stderr, 383 "libdwarf Internal error: free structs in chunk %d\n", 384 (int) alloc_area->aa_free_structs_in_chunk); 385 #endif 386 return NULL; 387 } 388 389 /* 390 The struct returned begins immediately after the 391 Dwarf_Alloc_Area_s struct. */ 392 ret_mem = mem_block + rounded_area_hdr_size; 393 alloc_area->aa_blob_start = 394 ret_mem + alloc_hdr->ah_bytes_one_struct; 395 alloc_area->aa_blob_end = mem_block + mem_block_size; 396 397 /* 398 Store pointer to chunk this struct belongs to in the first 399 few bytes. Return pointer to bytes after this pointer 400 storage. */ 401 *(Dwarf_Alloc_Area *) ret_mem = alloc_area; 402 ret_mem += _DW_RESERVE; 403 } 404 405 alloc_hdr->ah_last_alloc_area = alloc_area; 406 alloc_hdr->ah_struct_user_holds++; 407 memset(ret_mem,0, alloc_hdr->ah_bytes_one_struct - _DW_RESERVE); 408 return (ret_mem); 409 } 410 411 #endif /* ndef DWARF_SIMPLE_MALLOC */ 412 413 /* 414 This function returns a pointer to a region 415 of memory. For alloc_types that are not 416 strings or lists of pointers, only 1 struct 417 can be requested at a time. This is indicated 418 by an input count of 1. For strings, count 419 equals the length of the string it will 420 contain, i.e it the length of the string 421 plus 1 for the terminating null. For lists 422 of pointers, count is equal to the number of 423 pointers. For DW_DLA_FRAME_BLOCK, and 424 DW_DLA_LOC_BLOCK allocation types also, count 425 is the count of the number of structs needed. 426 427 This function cannot be used to allocate a 428 Dwarf_Debug_s struct. 429 */ 430 Dwarf_Ptr 431 _dwarf_get_alloc(Dwarf_Debug dbg, 432 Dwarf_Small alloc_type, Dwarf_Unsigned count) 433 { 434 Dwarf_Alloc_Hdr alloc_hdr; 435 436 Dwarf_Ptr ret_mem; 437 438 Dwarf_Signed size = 0; 439 unsigned int index; 440 unsigned int type = alloc_type; 441 442 if (dbg == NULL) { 443 return (NULL); 444 } 445 446 if (type >= ALLOC_AREA_INDEX_TABLE_MAX) { 447 /* internal error */ 448 return NULL; 449 } 450 index = index_into_allocated[type].ia_al_num; 451 /* zero also illegal but not tested for */ 452 453 /* If the Dwarf_Debug is not fully set up, we will get index 0 for 454 any type and must do something. 'Not fully set up' can only 455 happen for DW_DLA_ERROR, I (davea) believe, and for that we call 456 special code here.. */ 457 458 if (index == 0) { 459 if (alloc_type == DW_DLA_STRING) { 460 size = count; 461 } else if (alloc_type == DW_DLA_LIST) { 462 size = count * sizeof(Dwarf_Ptr); 463 } else if (alloc_type == DW_DLA_FRAME_BLOCK) { 464 size = count * sizeof(Dwarf_Frame_Op); 465 } else if (alloc_type == DW_DLA_LOC_BLOCK) { 466 size = count * sizeof(Dwarf_Loc); 467 } else if (alloc_type == DW_DLA_ADDR) { 468 size = count * 469 (sizeof(Dwarf_Addr) > sizeof(Dwarf_Off) ? 470 sizeof(Dwarf_Addr) : sizeof(Dwarf_Off)); 471 } else if (alloc_type == DW_DLA_ERROR) { 472 return _dwarf_special_no_dbg_error_malloc(); 473 } else { 474 /* If we get here, there is a disastrous programming error 475 somewhere. */ 476 #ifdef DEBUG 477 fprintf(stderr, 478 "libdwarf Internal error: type %d unexpected\n", 479 (int) type); 480 #endif 481 } 482 } else { 483 alloc_hdr = &dbg->de_alloc_hdr[index]; 484 if (alloc_hdr->ah_bytes_one_struct > 0) { 485 #ifdef DWARF_SIMPLE_MALLOC 486 size = alloc_hdr->ah_bytes_one_struct; 487 #else 488 return (_dwarf_find_memory(alloc_hdr)); 489 #endif 490 491 } else { 492 /* Special case: should not really happen at all. */ 493 if (type == DW_DLA_ERROR) { 494 /* dwarf_init failure. Because dbg is incomplete we 495 won't use it to record the malloc. */ 496 return _dwarf_special_no_dbg_error_malloc(); 497 } else { 498 /* If we get here, there is a disastrous programming 499 error somewhere. */ 500 #ifdef DWARF_SIMPLE_MALLOC 501 _dwarf_simple_malloc_botch(3); 502 #endif 503 #ifdef DEBUG 504 fprintf(stderr, 505 "libdwarf Internal error: Type %d unexpected\n", 506 (int) type); 507 #endif 508 } 509 } 510 } 511 512 ret_mem = malloc(size); 513 #ifdef DWARF_SIMPLE_MALLOC 514 _dwarf_simple_malloc_add_to_list(dbg,ret_mem,(unsigned long)size, 515 alloc_type); 516 #endif 517 if (ret_mem != NULL) 518 memset(ret_mem,0, size); 519 520 return (ret_mem); 521 } 522 523 524 /* 525 This function is used to deallocate a region of memory 526 that was obtained by a call to _dwarf_get_alloc. Note 527 that though dwarf_dealloc() is a public function, 528 _dwarf_get_alloc() isn't. 529 530 For lists, typically arrays of pointers, it is assumed 531 that the space was allocated by a direct call to malloc, 532 and so a straight free() is done. This is also the case 533 for variable length blocks such as DW_DLA_FRAME_BLOCK 534 and DW_DLA_LOC_BLOCK. 535 536 For strings, the pointer might point to a string in 537 .debug_info or .debug_string. After this is checked, 538 and if found not to be the case, a free() is done, 539 again on the assumption that a malloc was used to 540 obtain the space. 541 542 For other types of structs, a pointer to the chunk that 543 the struct was allocated out of, is present in the bytes 544 preceding the pointer passed in. For this chunk it is 545 checked whether all the structs in that chunk are now free. 546 If so, the entire chunk is free_ed. Otherwise, the space 547 is added to the free list for that chunk, and the free count 548 incremented. 549 550 This function does not return anything. 551 */ 552 void 553 dwarf_dealloc(Dwarf_Debug dbg, 554 Dwarf_Ptr space, Dwarf_Unsigned alloc_type) 555 { 556 Dwarf_Alloc_Hdr alloc_hdr; 557 Dwarf_Alloc_Area alloc_area; 558 unsigned int type = alloc_type; 559 unsigned int index; 560 561 if (space == NULL) { 562 return; 563 } 564 if (alloc_type == DW_DLA_ERROR) { 565 /* Get pointer to Dwarf_Alloc_Area this struct came from. See 566 dwarf_alloc.h ROUND_SIZE_WITH_POINTER stuff */ 567 alloc_area = 568 *(Dwarf_Alloc_Area *) ((char *) space - _DW_RESERVE); 569 if (alloc_area == 0) { 570 /* This is the special case of a failed dwarf_init(). Also 571 (and more signficantly) there are a variety of other 572 situations where libdwarf does not *know* what dbg is 573 involved (because of a libdwarf-caller-error) so 574 libdwarf uses NULL as the dbg. Those too wind up here. */ 575 _dwarf_free_special_error(space); 576 return; 577 } 578 579 } 580 if (dbg == NULL) { 581 /* App error, or an app that failed to succeed in a 582 dwarf_init() call. */ 583 return; 584 } 585 if (type >= ALLOC_AREA_INDEX_TABLE_MAX) { 586 /* internal or user app error */ 587 return; 588 } 589 590 index = index_into_allocated[alloc_type].ia_al_num; 591 /* 592 A string pointer may point into .debug_info or .debug_string. 593 Otherwise, they are directly malloc'ed. */ 594 if (index == 0) { 595 if (alloc_type == DW_DLA_STRING) { 596 if ((Dwarf_Small *) space >= dbg->de_debug_info && 597 (Dwarf_Small *) space < 598 dbg->de_debug_info + dbg->de_debug_info_size) 599 return; 600 601 if (dbg->de_debug_line != NULL && 602 (Dwarf_Small *) space >= dbg->de_debug_line && 603 (Dwarf_Small *) space < 604 dbg->de_debug_line + dbg->de_debug_line_size) 605 return; 606 607 if (dbg->de_debug_pubnames != NULL && 608 (Dwarf_Small *) space >= dbg->de_debug_pubnames && 609 (Dwarf_Small *) space < 610 dbg->de_debug_pubnames + dbg->de_debug_pubnames_size) 611 return; 612 613 if (dbg->de_debug_frame != NULL && 614 (Dwarf_Small *) space >= dbg->de_debug_frame && 615 (Dwarf_Small *) space < 616 dbg->de_debug_frame + dbg->de_debug_frame_size) 617 return; 618 619 if (dbg->de_debug_str != NULL && 620 (Dwarf_Small *) space >= dbg->de_debug_str && 621 (Dwarf_Small *) space < 622 dbg->de_debug_str + dbg->de_debug_str_size) 623 return; 624 625 if (dbg->de_debug_funcnames != NULL && 626 (Dwarf_Small *) space >= dbg->de_debug_funcnames && 627 (Dwarf_Small *) space < 628 dbg->de_debug_funcnames + dbg->de_debug_funcnames_size) 629 return; 630 631 if (dbg->de_debug_typenames != NULL && 632 (Dwarf_Small *) space >= dbg->de_debug_typenames && 633 (Dwarf_Small *) space < 634 dbg->de_debug_typenames + dbg->de_debug_typenames_size) 635 return; 636 637 if (dbg->de_debug_varnames != NULL && 638 (Dwarf_Small *) space >= dbg->de_debug_varnames && 639 (Dwarf_Small *) space < 640 dbg->de_debug_varnames + dbg->de_debug_varnames_size) 641 return; 642 643 if (dbg->de_debug_weaknames != NULL && 644 (Dwarf_Small *) space >= dbg->de_debug_weaknames && 645 (Dwarf_Small *) space < 646 dbg->de_debug_weaknames + dbg->de_debug_weaknames_size) 647 return; 648 649 free(space); 650 return; 651 } 652 653 if (alloc_type == DW_DLA_LIST || 654 alloc_type == DW_DLA_FRAME_BLOCK || 655 alloc_type == DW_DLA_LOC_BLOCK || 656 alloc_type == DW_DLA_ADDR) { 657 658 free(space); 659 return; 660 } 661 /* else is an alloc type that is not used */ 662 /* app or internal error */ 663 #ifdef DWARF_SIMPLE_MALLOC 664 _dwarf_simple_malloc_botch(4); 665 #endif 666 return; 667 668 } 669 670 #ifdef DWARF_SIMPLE_MALLOC 671 _dwarf_simple_malloc_delete_from_list(dbg, space, alloc_type); 672 free(space); 673 #else /* !DWARF_SIMPLE_MALLOC */ 674 alloc_hdr = &dbg->de_alloc_hdr[index]; 675 676 /* Get pointer to Dwarf_Alloc_Area this struct came from. See 677 dwarf_alloc.h ROUND_SIZE_WITH_POINTER stuff */ 678 alloc_area = *(Dwarf_Alloc_Area *) ((char *) space - _DW_RESERVE); 679 680 /* ASSERT: alloc_area != NULL 681 If NULL we could abort, let it coredump below, 682 or return, pretending all is well. We go 683 on, letting program crash. Is caller error. */ 684 685 /* 686 Check that the alloc_hdr field of the alloc_area we have is 687 pointing to the right alloc_hdr. This is used to catch use of 688 incorrect deallocation code by the user. */ 689 if (alloc_area->aa_alloc_hdr != alloc_hdr) { 690 /* If we get here, the user has called dwarf_dealloc wrongly or 691 there is some other disastrous error. By leaking mem here we 692 try to be safe... */ 693 #ifdef DEBUG 694 fprintf(stderr, 695 "libdwarf Internal error: type %d hdr mismatch %x %x area ptr %x\n", 696 (int) alloc_type, 697 (int) alloc_area->aa_alloc_hdr, 698 (int) alloc_hdr, (int) alloc_area); 699 #endif 700 return; 701 } 702 703 alloc_hdr->ah_struct_user_holds--; 704 alloc_area->aa_free_structs_in_chunk++; 705 706 /* 707 Give chunk back to malloc only when every struct is freed */ 708 if (alloc_area->aa_free_structs_in_chunk == 709 alloc_hdr->ah_structs_per_chunk) { 710 if (alloc_area->aa_prev != NULL) { 711 alloc_area->aa_prev->aa_next = alloc_area->aa_next; 712 } else { 713 alloc_hdr->ah_alloc_area_head = alloc_area->aa_next; 714 } 715 716 if (alloc_area->aa_next != NULL) { 717 alloc_area->aa_next->aa_prev = alloc_area->aa_prev; 718 } 719 720 alloc_hdr->ah_chunks_allocated--; 721 722 if (alloc_area == alloc_hdr->ah_last_alloc_area) { 723 alloc_hdr->ah_last_alloc_area = NULL; 724 } 725 memset(alloc_area,0, sizeof(*alloc_area)); 726 free(alloc_area); 727 } 728 729 else { 730 ((Dwarf_Free_List) space)->fl_next = alloc_area->aa_free_list; 731 alloc_area->aa_free_list = space; 732 } 733 #endif /* !DWARF_SIMPLE_MALLOC */ 734 } 735 736 737 /* 738 Allocates space for a Dwarf_Debug_s struct, 739 since one does not exist. 740 */ 741 Dwarf_Debug 742 _dwarf_get_debug(void 743 ) 744 { 745 Dwarf_Debug dbg; 746 747 dbg = (Dwarf_Debug) malloc(sizeof(struct Dwarf_Debug_s)); 748 if (dbg == NULL) 749 return (NULL); 750 else 751 memset(dbg,0, sizeof(struct Dwarf_Debug_s)); 752 753 return (dbg); 754 } 755 756 757 /* 758 Sets up the Dwarf_Debug_s struct for all the 759 allocation types currently defined. 760 Allocation types DW_DLA_STRING, DW_DLA_LIST, 761 DW_DLA_FRAME_BLOCK, DW_DLA_LOC_BLOCK are 762 malloc'ed directly. 763 764 This routine should be called after _dwarf_setup(), 765 so that information about the sizes of the Dwarf 766 sections can be used to decide the number of 767 structs of each type malloc'ed. 768 769 Also DW_DLA_ELLIST, DW_DLA_BOUNDS, DW_DLA_TYPE, 770 DW_DLA_SUBSCR, DW_DLA_LINEBUF allocation types 771 are currently not used. 772 The ah_bytes_one_struct and ah_structs_per_chunk fields for 773 these types have been set to 1 for efficiency 774 in dwarf_get_alloc(). 775 776 Ah_alloc_num should be greater than 1 for all 777 types that are currently being used. 778 779 Therefore, for these allocation types the 780 ah_bytes_one_struct, and ah_structs_per_chunk fields do not 781 need to be initialized. 782 783 Being an internal routine, assume proper dbg. 784 785 786 787 788 */ 789 /* 790 ** Set up all the Dwarf_Alloc_Hdr records. 791 */ 792 793 Dwarf_Debug 794 _dwarf_setup_debug(Dwarf_Debug dbg) 795 { 796 int i; 797 798 for (i = 1; i <= MAX_DW_DLA; i++) { 799 const struct ial_s *ialp = &index_into_allocated[i]; 800 unsigned int hdr_index = ialp->ia_al_num; 801 Dwarf_Word str_size = ialp->ia_struct_size; 802 Dwarf_Word str_count = ialp->ia_base_count; 803 Dwarf_Word rnded_size = ROUND_SIZE_WITH_POINTER(str_size); 804 805 Dwarf_Alloc_Hdr alloc_hdr = &dbg->de_alloc_hdr[hdr_index]; 806 807 alloc_hdr->ah_bytes_one_struct = (Dwarf_Half) rnded_size; 808 809 /* ah_structs_per_chunk must be >0 else we are in trouble */ 810 alloc_hdr->ah_structs_per_chunk = str_count; 811 alloc_hdr->ah_bytes_malloc_per_chunk = rnded_size * str_count; 812 } 813 return (dbg); 814 } 815 816 /* 817 This function prints out the statistics 818 collected on allocation of memory chunks. 819 */ 820 void 821 dwarf_print_memory_stats(Dwarf_Debug dbg) 822 { 823 Dwarf_Alloc_Hdr alloc_hdr; 824 Dwarf_Shalf i; 825 826 /* 827 Alloc types start at 1, not 0. Hence, the first NULL string, 828 and also a size of MAX_DW_DLA + 1. */ 829 char *alloc_type_name[MAX_DW_DLA + 1] = { 830 "", 831 "DW_DLA_STRING", 832 "DW_DLA_LOC", 833 "DW_DLA_LOCDESC", 834 "DW_DLA_ELLIST", 835 "DW_DLA_BOUNDS", 836 "DW_DLA_BLOCK", 837 "DW_DLA_DEBUG", 838 "DW_DLA_DIE", 839 "DW_DLA_LINE", 840 "DW_DLA_ATTR", 841 "DW_DLA_TYPE", 842 "DW_DLA_SUBSCR", 843 "DW_DLA_GLOBAL", 844 "DW_DLA_ERROR", 845 "DW_DLA_LIST", 846 "DW_DLA_LINEBUF", 847 "DW_DLA_ARANGE", 848 "DW_DLA_ABBREV", 849 "DW_DLA_FRAME_OP", 850 "DW_DLA_CIE", 851 "DW_DLA_FDE", 852 "DW_DLA_LOC_BLOCK", 853 "DW_DLA_FRAME_BLOCK", 854 "DW_DLA_FUNC", 855 "DW_DLA_TYPENAME", 856 "DW_DLA_VAR", 857 "DW_DLA_WEAK", 858 "DW_DLA_ADDR", 859 "DW_DLA_ABBREV_LIST", 860 "DW_DLA_CHAIN", 861 "DW_DLA_CU_CONTEXT", 862 "DW_DLA_FRAME", 863 "DW_DLA_GLOBAL_CONTEXT", 864 "DW_DLA_FILE_ENTRY", 865 "DW_DLA_LINE_CONTEXT", 866 "DW_DLA_LOC_CHAIN", 867 "DW_DLA_HASH_TABLE", 868 "DW_DLA_FUNC_CONTEXT", 869 "DW_DLA_TYPENAME_CONTEXT", 870 "DW_DLA_VAR_CONTEXT", 871 "DW_DLA_WEAK_CONTEXT" 872 }; 873 874 if (dbg == NULL) 875 return; 876 877 printf("Size of Dwarf_Debug %4ld bytes\n", 878 (long) sizeof(*dbg)); 879 printf("Size of Dwarf_Alloc_Hdr_s %4ld bytes\n", 880 (long) sizeof(struct Dwarf_Alloc_Hdr_s)); 881 printf("size of Dwarf_Alloc_Area_s %4ld bytes\n", 882 (long) sizeof(struct Dwarf_Alloc_Area_s)); 883 884 printf(" Alloc Type Curr Structs byt str\n"); 885 printf(" ---------- ---- ------- per per\n"); 886 for (i = 1; i <= MAX_DW_DLA; i++) { 887 int indx = index_into_allocated[i].ia_al_num; 888 889 alloc_hdr = &dbg->de_alloc_hdr[indx]; 890 if (alloc_hdr->ah_bytes_one_struct != 1) { 891 printf("%2d %-25s %6d %8d %6d %6d\n", 892 (int) i, 893 alloc_type_name[i], 894 (int) alloc_hdr->ah_chunks_allocated, 895 (int) alloc_hdr->ah_struct_user_holds, 896 (int) alloc_hdr->ah_bytes_malloc_per_chunk, 897 (int) alloc_hdr->ah_structs_per_chunk); 898 } 899 } 900 } 901 902 903 #ifndef DWARF_SIMPLE_MALLOC 904 /* 905 This function is used to recursively 906 free the chunks still allocated, and 907 forward chained through the aa_next 908 pointer. 909 */ 910 static void 911 _dwarf_recursive_free(Dwarf_Alloc_Area alloc_area) 912 { 913 if (alloc_area->aa_next != NULL) { 914 _dwarf_recursive_free(alloc_area->aa_next); 915 } 916 917 alloc_area->aa_next = 0; 918 alloc_area->aa_prev = 0; 919 free(alloc_area); 920 } 921 #endif 922 923 /* 924 Used to free all space allocated for this Dwarf_Debug. 925 The caller should assume that the Dwarf_Debug pointer 926 itself is no longer valid upon return from this function. 927 928 In case of difficulty, this function simply returns quietly. 929 */ 930 int 931 _dwarf_free_all_of_one_debug(Dwarf_Debug dbg) 932 { 933 Dwarf_Alloc_Hdr alloc_hdr; 934 Dwarf_Shalf i; 935 936 if (dbg == NULL) 937 return (DW_DLV_ERROR); 938 939 #ifdef DWARF_SIMPLE_MALLOC 940 if(dbg->de_simple_malloc_base) { 941 struct simple_malloc_record_s *smp = dbg->de_simple_malloc_base; 942 while( smp) 943 { 944 int i; 945 struct simple_malloc_record_s *prev_smp = 0; 946 947 for(i = 0; i < smp->sr_used; ++i) { 948 struct simple_malloc_entry_s *cur; 949 cur = &smp->sr_entry[i]; 950 if(cur->se_addr != 0) { 951 free(cur->se_addr); 952 cur->se_addr = 0; 953 } 954 } 955 prev_smp = smp; 956 smp = smp->sr_next; 957 free(prev_smp); 958 } 959 dbg->de_simple_malloc_base = 0; 960 dbg->de_simple_malloc_current = 0; 961 } 962 #else 963 for (i = 1; i < ALLOC_AREA_REAL_TABLE_MAX; i++) { 964 int indx = i; 965 966 alloc_hdr = &dbg->de_alloc_hdr[indx]; 967 if (alloc_hdr->ah_alloc_area_head != NULL) { 968 _dwarf_recursive_free(alloc_hdr->ah_alloc_area_head); 969 } 970 } 971 972 #endif 973 974 memset(dbg,0, sizeof(*dbg)); /* prevent accidental use later */ 975 free(dbg); 976 return (DW_DLV_OK); 977 } 978 979 /* A special case: we have no dbg, no alloc header etc. 980 So create something out of thin air that we can recognize 981 in dwarf_dealloc. 982 Something with the prefix (prefix space hidden from caller). 983 984 Only applies to DW_DLA_ERROR, making up an error record. 985 */ 986 987 struct Dwarf_Error_s * 988 _dwarf_special_no_dbg_error_malloc(void) 989 { 990 /* the union unused things are to guarantee proper alignment */ 991 union u { 992 Dwarf_Alloc_Area ptr_not_used; 993 struct Dwarf_Error_s base_not_used; 994 char data_space[sizeof(struct Dwarf_Error_s) + 995 (_DW_RESERVE * 2)]; 996 }; 997 char *mem; 998 999 mem = malloc(sizeof(union u)); 1000 1001 if (mem == 0) { 1002 return 0; 1003 1004 } 1005 memset(mem,0, sizeof(union u)); 1006 mem += _DW_RESERVE; 1007 return (struct Dwarf_Error_s *) mem; 1008 } 1009 1010 /* The free side of _dwarf_special_no_dbg_error_malloc() 1011 */ 1012 static void 1013 _dwarf_free_special_error(Dwarf_Ptr space) 1014 { 1015 char *mem = (char *) space; 1016 1017 mem -= _DW_RESERVE; 1018 free(mem); 1019 } 1020 1021 1022 #ifdef DWARF_SIMPLE_MALLOC 1023 /* here solely for planting a breakpoint. */ 1024 /* ARGSUSED */ 1025 void 1026 _dwarf_simple_malloc_botch(int err) 1027 { 1028 } 1029 static void 1030 _dwarf_simple_malloc_add_to_list(Dwarf_Debug dbg, 1031 Dwarf_Ptr addr, 1032 unsigned long size, 1033 short alloc_type) 1034 { 1035 struct simple_malloc_record_s *cur; 1036 struct simple_malloc_entry_s *newentry; 1037 if (!dbg->de_simple_malloc_current) { 1038 /* First entry to this routine. */ 1039 dbg->de_simple_malloc_current = 1040 malloc(sizeof(struct simple_malloc_record_s)); 1041 if(!dbg->de_simple_malloc_current) { 1042 return; /* no memory, give up */ 1043 } 1044 memset(dbg->de_simple_malloc_current, 1045 0, 1046 sizeof(struct simple_malloc_record_s)); 1047 dbg->de_simple_malloc_base = dbg->de_simple_malloc_current; 1048 } 1049 cur = dbg->de_simple_malloc_current; 1050 1051 if(cur->sr_used >= DSM_BLOCK_COUNT) { 1052 /* better not be > than as that means chaos */ 1053 1054 /* Create a new block to link at the head. */ 1055 1056 struct simple_malloc_record_s *newblock = 1057 malloc(sizeof(struct simple_malloc_record_s)); 1058 if(!newblock) { 1059 return; /* Can do nothing, out of memory */ 1060 } 1061 memset(newblock,0, sizeof(struct simple_malloc_record_s)); 1062 /* Link the new block at the head of the chain, 1063 and make it 'current' 1064 */ 1065 dbg->de_simple_malloc_current = newblock; 1066 newblock->sr_next = cur; 1067 cur = newblock; 1068 } 1069 newentry = &cur->sr_entry[cur->sr_used]; 1070 newentry->se_addr = addr; 1071 newentry->se_size = size; 1072 newentry->se_type = alloc_type; 1073 ++cur->sr_used; 1074 } 1075 /* 1076 DWARF_SIMPLE_MALLOC is for testing the hypothesis that the existing 1077 complex malloc scheme in libdwarf is pointless complexity. 1078 1079 DWARF_SIMPLE_MALLOC also makes it easy for a malloc-tracing 1080 tool to verify libdwarf malloc has no botches (though of course 1081 such does not test the complicated standard-libdwarf-alloc code). 1082 1083 To properly answer the question, the simple-malloc allocate 1084 and delete should be something other than a simple list. 1085 Perhaps a heap, or perhaps a red-black tree. 1086 1087 */ 1088 static void 1089 _dwarf_simple_malloc_delete_from_list(Dwarf_Debug dbg, 1090 Dwarf_Ptr space, 1091 short alloc_type) 1092 { 1093 if(space == 0) { 1094 _dwarf_simple_malloc_botch(6); 1095 } 1096 if(dbg->de_simple_malloc_base) { 1097 struct simple_malloc_record_s *smp = dbg->de_simple_malloc_base; 1098 while( smp) 1099 { 1100 int i; 1101 1102 for(i = 0; i < smp->sr_used; ++i) { 1103 struct simple_malloc_entry_s *cur; 1104 cur = &smp->sr_entry[i]; 1105 if(cur->se_addr == space) { 1106 if(cur->se_type != alloc_type ) { 1107 _dwarf_simple_malloc_botch(0); 1108 } 1109 cur->se_addr = 0; 1110 return; 1111 } 1112 } 1113 smp = smp->sr_next; 1114 } 1115 } 1116 /* Never found the space */ 1117 _dwarf_simple_malloc_botch(1); 1118 return; 1119 1120 } 1121 #endif 1122 1123