എൽഫ് ഫയൽ. ഡീബഗ്ഗിംഗ് വിവരങ്ങൾ (DWARF) സ്വമേധയാ ഞങ്ങൾ ഒരു ELF ഫയൽ സൃഷ്ടിക്കുന്നു (ARM മൈക്രോകൺട്രോളറുകൾക്ക്). വേരിയബിളുകളും കോൺസ്റ്റന്റുകളും സൃഷ്ടിക്കുന്നു

ഈ അവലോകനത്തിൽ ഞങ്ങൾ ഈ ഫോർമാറ്റിന്റെ 32-ബിറ്റ് പതിപ്പിനെക്കുറിച്ച് മാത്രമേ സംസാരിക്കൂ, കാരണം ഞങ്ങൾക്ക് ഇതുവരെ 64-ബിറ്റ് പതിപ്പ് ആവശ്യമില്ല.

ഏതൊരു ELF ഫയലിലും (ഈ ഫോർമാറ്റിന്റെ ഒബ്‌ജക്റ്റ് മൊഡ്യൂളുകൾ ഉൾപ്പെടെ) ഇനിപ്പറയുന്ന ഭാഗങ്ങൾ അടങ്ങിയിരിക്കുന്നു:

  • ELF ഫയൽ തലക്കെട്ട്;
  • പ്രോഗ്രാം വിഭാഗങ്ങളുടെ പട്ടിക (ഒബ്ജക്റ്റ് മൊഡ്യൂളുകളിൽ ഇല്ലായിരിക്കാം);
  • ELF ഫയൽ വിഭാഗങ്ങൾ;
  • സെക്ഷൻ ടേബിൾ (എക്സിക്യൂട്ടിംഗ് മൊഡ്യൂളിൽ ഇല്ലായിരിക്കാം);
  • പ്രകടന കാരണങ്ങളാൽ, ELF ഫോർമാറ്റ് ബിറ്റ് ഫീൽഡുകൾ ഉപയോഗിക്കുന്നില്ല. കൂടാതെ എല്ലാ ഘടനകളും സാധാരണയായി 4 ബൈറ്റ് വിന്യസിച്ചിരിക്കുന്നു.

ഇനി ELF ഫയൽ ഹെഡറുകളിൽ ഉപയോഗിക്കുന്ന തരങ്ങൾ നോക്കാം:

ഇനി നമുക്ക് ഫയൽ തലക്കെട്ട് നോക്കാം:

EI_NIDENT 16 struct elf32_hdr നിർവ്വചിക്കുക ( ഒപ്പിടാത്ത ചാർ e_ident; Elf32_Half e_type; Elf32_Half e_machine; Elf32_Word e_version; Elf32_Addr e_hdr; Offe e_shoff;Elf32_Word e_flags Elf32_Half e_shnum; Elf32_Half e_shstrndx; );

e_ident അറേയിൽ സിസ്റ്റത്തെക്കുറിച്ചുള്ള വിവരങ്ങൾ അടങ്ങിയിരിക്കുന്നു കൂടാതെ നിരവധി ഉപഫീൽഡുകൾ അടങ്ങിയിരിക്കുന്നു.

സ്ട്രക്റ്റ് ( ഒപ്പിടാത്ത ചാർ ഈ_ക്ലാസ്; ഒപ്പിടാത്ത ചാർ ഈ_ഡാറ്റ

  • ei_magic - എല്ലാ ELF ഫയലുകൾക്കുമുള്ള സ്ഥിരമായ മൂല്യം, (0x7f, "E", "L", "F")
  • ei_class - ELF ഫയൽ ക്ലാസ് (1 - 32 ബിറ്റുകൾ, 2 - 64 ബിറ്റുകൾ ഞങ്ങൾ പരിഗണിക്കില്ല)
  • ei_data - ഈ ഫയലിന്റെ ബൈറ്റ് ഓർഡർ നിർണ്ണയിക്കുന്നു (ഈ ഓർഡർ പ്ലാറ്റ്‌ഫോമിനെ ആശ്രയിച്ചിരിക്കുന്നു, അത് ഫോർവേഡ് (LSB അല്ലെങ്കിൽ 1) അല്ലെങ്കിൽ റിവേഴ്സ് (MSB അല്ലെങ്കിൽ 2) ആകാം) ഇന്റൽ പ്രോസസ്സറുകൾക്ക്, മൂല്യം 1 മാത്രമേ അനുവദനീയമായിട്ടുള്ളൂ.
  • ei_version തികച്ചും ഉപയോഗശൂന്യമായ ഒരു ഫീൽഡാണ്, അത് 1 (EV_CURRENT) ന് തുല്യമല്ലെങ്കിൽ ഫയൽ തെറ്റായി കണക്കാക്കും.

ഓപ്പറേറ്റിംഗ് സിസ്റ്റങ്ങൾ അവരുടെ തിരിച്ചറിയൽ വിവരങ്ങൾ ei_pad ഫീൽഡിൽ സൂക്ഷിക്കുന്നു. ഈ ഫീൽഡ് ശൂന്യമായിരിക്കാം. അത് നമുക്കും പ്രശ്നമല്ല.

e_type തലക്കെട്ട് ഫീൽഡിൽ ഒന്നിലധികം മൂല്യങ്ങൾ അടങ്ങിയിരിക്കാം, എക്സിക്യൂട്ടബിൾ ഫയലുകൾക്ക് ഇത് ET_EXEC 2 ന് തുല്യമായിരിക്കണം

e_machine - ഈ എക്സിക്യൂട്ടബിൾ ഫയൽ പ്രവർത്തിപ്പിക്കാൻ കഴിയുന്ന പ്രോസസർ നിർണ്ണയിക്കുന്നു (ഞങ്ങൾക്ക്, സ്വീകാര്യമായ മൂല്യം EM_386 3 ആണ്)

e_version ഫീൽഡ് തലക്കെട്ടിൽ നിന്നുള്ള ei_version ഫീൽഡുമായി യോജിക്കുന്നു.

e_entry ഫീൽഡ് പ്രോഗ്രാമിന്റെ ആരംഭ വിലാസം നിർവചിക്കുന്നു, അത് പ്രോഗ്രാം ആരംഭിക്കുന്നതിന് മുമ്പ് eip-ൽ സ്ഥാപിച്ചിരിക്കുന്നു.

മെമ്മറിയിലേക്ക് പ്രോഗ്രാമുകൾ ലോഡ് ചെയ്യാൻ ഉപയോഗിക്കുന്ന പ്രോഗ്രാം സെക്ഷൻ ടേബിൾ സ്ഥിതി ചെയ്യുന്ന ഫയലിന്റെ ആരംഭം മുതൽ ഓഫ്സെറ്റ് e_phoff ഫീൽഡ് വ്യക്തമാക്കുന്നു.

എല്ലാ ഫീൽഡുകളുടെയും ഉദ്ദേശ്യം ഞാൻ പട്ടികപ്പെടുത്തില്ല; എല്ലാം ലോഡുചെയ്യുന്നതിന് ആവശ്യമില്ല. രണ്ടെണ്ണം കൂടി ഞാൻ വിവരിക്കാം.

പ്രോഗ്രാം സെക്ഷൻ ടേബിളിലെ എൻട്രിയുടെ വലുപ്പം e_phentsize ഫീൽഡ് വ്യക്തമാക്കുന്നു.

കൂടാതെ പ്രോഗ്രാം സെക്ഷൻ ടേബിളിലെ എൻട്രികളുടെ എണ്ണം e_phnum ഫീൽഡ് നിർണ്ണയിക്കുന്നു.

പ്രോഗ്രാമുകൾ ലിങ്ക് ചെയ്യാൻ സെക്ഷൻ ടേബിൾ (പ്രോഗ്രാം വിഭാഗങ്ങളല്ല) ഉപയോഗിക്കുന്നു. ഞങ്ങൾ അത് പരിഗണിക്കുകയില്ല. ചലനാത്മകമായി ലിങ്ക് ചെയ്‌ത മൊഡ്യൂളുകളും ഞങ്ങൾ പരിഗണിക്കില്ല. ഈ വിഷയം തികച്ചും സങ്കീർണ്ണവും ആദ്യ പരിചയക്കാരന് അനുയോജ്യവുമല്ല. :)

ഇപ്പോൾ പ്രോഗ്രാം വിഭാഗങ്ങളെക്കുറിച്ച്. പ്രോഗ്രാം സെക്ഷൻ ടേബിൾ എൻട്രി ഫോർമാറ്റ് ഇപ്രകാരമാണ്:

struct elf32_phdr (Elf32_Word p_type; Elf32_Off p_offset; Elf32_Addr p_vaddr; Elf32_Addr p_paddr; Elf32_Word p_filesz; Elf32_Word p_mems_Word p_mems_2; ; );

ഫീൽഡുകളെക്കുറിച്ച് കൂടുതലറിയുക.

  • p_type - പ്രോഗ്രാം വിഭാഗത്തിന്റെ തരം നിർണ്ണയിക്കുന്നു. ഇതിന് നിരവധി മൂല്യങ്ങൾ എടുക്കാം, പക്ഷേ ഞങ്ങൾക്ക് ഒന്നിൽ മാത്രമേ താൽപ്പര്യമുള്ളൂ. PT_LOAD(1). വിഭാഗം ഈ തരത്തിലുള്ളതാണെങ്കിൽ, അത് മെമ്മറിയിലേക്ക് ലോഡ് ചെയ്യാൻ ഉദ്ദേശിച്ചുള്ളതാണ്.
  • p_offset - ഈ വിഭാഗം ആരംഭിക്കുന്ന ഫയലിലെ ഓഫ്സെറ്റ് നിർണ്ണയിക്കുന്നു.
  • p_vaddr - ഈ വിഭാഗം മെമ്മറിയിലേക്ക് ലോഡ് ചെയ്യേണ്ട വിർച്ച്വൽ വിലാസം നിർവചിക്കുന്നു.
  • p_paddr - ഈ വിഭാഗം ലോഡ് ചെയ്യേണ്ട ഭൗതിക വിലാസം നിർവചിക്കുന്നു. ഈ ഫീൽഡ് ഓപ്ഷണൽ ആണ് കൂടാതെ ചില പ്ലാറ്റ്ഫോമുകളിൽ മാത്രം അർത്ഥമുള്ളതാണ്.
  • p_filesz - ഫയലിലെ വിഭാഗത്തിന്റെ വലുപ്പം നിർണ്ണയിക്കുന്നു.
  • p_memsz - മെമ്മറി വിഭാഗത്തിന്റെ വലുപ്പം നിർണ്ണയിക്കുന്നു. ഈ മൂല്യം മുമ്പത്തേതിനേക്കാൾ കൂടുതലായിരിക്കാം. മെമ്മറിയിലെ വിഭാഗങ്ങളിലേക്കുള്ള ആക്സസ് തരം p_flag ഫീൽഡ് നിർണ്ണയിക്കുന്നു. ചില ഭാഗങ്ങൾ നടത്താം, ചിലത് എഴുതാം. നിലവിലുള്ള സിസ്റ്റങ്ങളിൽ എല്ലാം വായിക്കാൻ ലഭ്യമാണ്.

ELF ഫോർമാറ്റ് ലോഡുചെയ്യുന്നു.

ഞങ്ങൾ തലക്കെട്ട് കുറച്ച് മനസ്സിലാക്കി. ഇപ്പോൾ ഞാൻ ELF ഫോർമാറ്റിൽ ഒരു ബൈനറി ഫയൽ ലോഡ് ചെയ്യുന്നതിനുള്ള ഒരു അൽഗോരിതം നൽകും. അൽഗോരിതം സ്കീമാറ്റിക് ആണ്, അത് ഒരു വർക്കിംഗ് പ്രോഗ്രാമായി കണക്കാക്കരുത്.

Int LoadELF (അൺ സൈൻ ചെയ്യാത്ത ചാർ *ബിൻ) ( struct elf32_hdr *EH = (struct elf32_hdr *)bin; struct elf32_phdr *EPH; എങ്കിൽ (EH->e_ident != 0x7f || // "e_E_E_E_E_E_ident" || EH->e_ident != "L" || EH->e_ident != "F" || EH->e_ident != ELFCLASS32 || // ക്ലാസ് EH->e_ident != ELFDATA2LSB || // byte ഓർഡർ EH->e_ident != EV_CURRENT || // പതിപ്പ് EH->e_type != ET_EXEC || // ടൈപ്പ് ചെയ്യുക EH->e_machine != EM_386 || // പ്ലാറ്റ്ഫോം EH->e_version != EV_CURRENT) // വീണ്ടും പതിപ്പ്, ELF_WRONG തിരികെ നൽകുക; EPH = (struct elf32_phdr *)(bin + EH->e_phoff); അതേസമയം (EH->e_phnum--) ((EPH->p_type == PT_LOAD) memcpy (EPH->p_vaddr) , bin + EPH->p_offset, EPH->p_filesz); EPH = (struct elf32_phdr *)((അൺസൈൻഡ് ചാർ *)EPH + EH->e_phentsize); ) ELF_OK മടങ്ങുക; )

ഗുരുതരമായി, EPH->p_flags ഫീൽഡുകൾ വിശകലനം ചെയ്യുകയും ഉചിതമായ പേജുകളിലേക്ക് ആക്സസ് അവകാശങ്ങൾ നൽകുകയും ചെയ്യുന്നത് മൂല്യവത്താണ്, മാത്രമല്ല പകർത്തുന്നത് ഇവിടെ പ്രവർത്തിക്കില്ല, പക്ഷേ ഇത് ഫോർമാറ്റുമായി ബന്ധപ്പെട്ടതല്ല, മെമ്മറി അലോക്കേഷനുമായി ബന്ധപ്പെട്ടിരിക്കുന്നു. അതിനാൽ, ഞങ്ങൾ ഇതിനെക്കുറിച്ച് ഇപ്പോൾ സംസാരിക്കില്ല.

PE ഫോർമാറ്റ്.

പല തരത്തിലും ഇത് ELF ഫോർമാറ്റിനോട് സാമ്യമുള്ളതാണ്, മാത്രമല്ല ഡൗൺലോഡ് ചെയ്യുന്നതിനായി ലഭ്യമായ വിഭാഗങ്ങളും ഇതിൽ ഉണ്ടായിരിക്കണം എന്നതിൽ അതിശയിക്കാനില്ല.

Microsoft-ലെ മറ്റെല്ലാം പോലെ :) PE ഫോർമാറ്റ് EXE ഫോർമാറ്റിനെ അടിസ്ഥാനമാക്കിയുള്ളതാണ്. ഫയൽ ഘടന ഇപ്രകാരമാണ്:

  • 00h - EXE തലക്കെട്ട് (ഞാൻ അത് നോക്കില്ല, ഡോസിന്റെ അത്രയും പഴയതാണ്. :)
  • 20h - OEM തലക്കെട്ട് (അതിൽ കാര്യമായ ഒന്നും ഇല്ല);
  • 3сh - ഫയലിലെ യഥാർത്ഥ PE ഹെഡറിന്റെ ഓഫ്സെറ്റ് (dword).
  • സ്റ്റബ് ചലന പട്ടിക;
  • അപൂർണ്ണം;
  • PE തലക്കെട്ട്;
  • ഒബ്ജക്റ്റ് ടേബിൾ;
  • ഫയൽ വസ്തുക്കൾ;

യഥാർത്ഥ മോഡിൽ പ്രവർത്തിക്കുന്ന ഒരു പ്രോഗ്രാമാണ് സ്റ്റബ്, ചില പ്രാഥമിക പ്രവർത്തനങ്ങൾ ചെയ്യുന്നു. ഇത് ഇല്ലായിരിക്കാം, പക്ഷേ ചിലപ്പോൾ അത് ആവശ്യമായി വന്നേക്കാം.

ഞങ്ങൾക്ക് അൽപ്പം വ്യത്യസ്തമായ എന്തെങ്കിലും താൽപ്പര്യമുണ്ട്, PE തലക്കെട്ട്.

അതിന്റെ ഘടന ഇപ്രകാരമാണ്:

struct pe_hdr ( ഒപ്പിടാത്ത നീളമുള്ള pe_sign; ഒപ്പിടാത്ത ഹ്രസ്വ pe_cputype; ഒപ്പിടാത്ത ഹ്രസ്വ pe_objnum; ഒപ്പിടാത്ത നീണ്ട pe_time; ഒപ്പിടാത്ത നീണ്ട pe_cofftbl_off; ഒപ്പിടാത്ത നീളമുള്ള pe_cofftbl_size; unsigned shortspe_sign; pe_magic; ഒപ്പിടാത്ത ഹ്രസ്വ pe_link_ver; ഒപ്പിടാത്ത നീളമുള്ള pe_code_size; ; ഒപ്പിടാത്ത നീളമുള്ള pe_udata_size; ഒപ്പിടാത്ത നീളമുള്ള pe_entry; ഒപ്പിടാത്ത നീളമുള്ള pe_code_base; ഒപ്പിടാത്ത നീളമുള്ള pe_data_ബേസ്;

അവിടെ ഒരുപാട് സാധനങ്ങൾ ഉണ്ട്. ഈ തലക്കെട്ടിന്റെ വലിപ്പം 248 ബൈറ്റുകൾ ആണെന്ന് പറഞ്ഞാൽ മതിയാകും.

ഈ ഫീൽഡുകളിൽ ഭൂരിഭാഗവും ഉപയോഗിക്കുന്നില്ല എന്നതാണ് പ്രധാന കാര്യം. (ആരാണ് ഇതുപോലെ നിർമ്മിക്കുന്നത്?) ഇല്ല, അവർക്ക് തീർച്ചയായും അറിയപ്പെടുന്ന ഒരു ഉദ്ദേശ്യമുണ്ട്, പക്ഷേ എന്റെ ടെസ്റ്റ് പ്രോഗ്രാമിൽ, ഉദാഹരണത്തിന്, pe_code_base, pe_code_size തുടങ്ങിയ ഫീൽഡുകളിൽ പൂജ്യങ്ങൾ അടങ്ങിയിരിക്കുന്നു, പക്ഷേ അത് നന്നായി പ്രവർത്തിക്കുന്നു. ഒബ്ജക്റ്റ് ടേബിളിനെ അടിസ്ഥാനമാക്കിയാണ് ഫയൽ ലോഡ് ചെയ്തതെന്നാണ് നിഗമനം. അതിനെക്കുറിച്ച് ഞങ്ങൾ സംസാരിക്കും.

ഒബ്‌ജക്റ്റ് പട്ടിക PE തലക്കെട്ടിന് തൊട്ടുപിന്നാലെ പിന്തുടരുന്നു. ഈ പട്ടികയിലെ എൻട്രികൾക്ക് ഇനിപ്പറയുന്ന ഫോർമാറ്റ് ഉണ്ട്:

struct pe_ohdr ( ഒപ്പിടാത്ത ചാർ ഒ_വിസൈസ്

  • o_name - വിഭാഗത്തിന്റെ പേര്, ഇത് ലോഡുചെയ്യുന്നതിൽ തികച്ചും നിസ്സംഗതയാണ്;
  • o_vsize - മെമ്മറി വിഭാഗത്തിന്റെ വലിപ്പം;
  • o_vaddr - ഇമേജ്ബേസുമായി ബന്ധപ്പെട്ട മെമ്മറി വിലാസം;
  • o_psize - ഫയലിലെ സെക്ഷൻ വലുപ്പം;
  • o_poff - ഫയലിലെ സെക്ഷൻ ഓഫ്സെറ്റ്;
  • o_flags - സെക്ഷൻ ഫ്ലാഗുകൾ;

പതാകകൾ സൂക്ഷ്മമായി പരിശോധിക്കുന്നത് മൂല്യവത്താണ്.

  • 00000004h - 16 ബിറ്റ് ഓഫ്‌സെറ്റുകൾ ഉള്ള കോഡിനായി ഉപയോഗിക്കുന്നു
  • 00000020h - കോഡ് വിഭാഗം
  • 00000040h - ആരംഭിച്ച ഡാറ്റ വിഭാഗം
  • 00000080h - ആരംഭിക്കാത്ത ഡാറ്റ വിഭാഗം
  • 00000200h - അഭിപ്രായങ്ങൾ അല്ലെങ്കിൽ മറ്റേതെങ്കിലും തരത്തിലുള്ള വിവരങ്ങൾ
  • 00000400h - ഓവർലേ വിഭാഗം
  • 00000800h - പ്രോഗ്രാം ചിത്രത്തിന്റെ ഭാഗമാകില്ല
  • 00001000h - പൊതുവായ ഡാറ്റ
  • 00500000h - മറ്റുവിധത്തിൽ വ്യക്തമാക്കിയിട്ടില്ലെങ്കിൽ ഡിഫോൾട്ട് വിന്യാസം
  • 02000000h - മെമ്മറിയിൽ നിന്ന് അൺലോഡ് ചെയ്യാം
  • 04000000h - കാഷെ ചെയ്തിട്ടില്ല
  • 08000000h - പേജ് ചെയ്തിട്ടില്ല
  • 10000000h - പങ്കിട്ടു
  • 20000000h - ചെയ്യാൻ കഴിയും
  • 40000000h - വായിക്കാൻ കഴിയും
  • 80000000h - നിങ്ങൾക്ക് എഴുതാം

വീണ്ടും, പങ്കിട്ട, ഓവർലേ വിഭാഗങ്ങളെക്കുറിച്ച് ഞാൻ സംസാരിക്കില്ല, ഞങ്ങൾക്ക് കോഡ്, ഡാറ്റ, ആക്സസ് അവകാശങ്ങൾ എന്നിവയിൽ താൽപ്പര്യമുണ്ട്.

പൊതുവേ, ബൈനറി ഫയൽ ഡൗൺലോഡ് ചെയ്യാൻ ഈ വിവരങ്ങൾ ഇതിനകം മതിയാകും.

PE ഫോർമാറ്റ് ലോഡുചെയ്യുന്നു.

int LoadPE (അൺ സൈൻ ചെയ്യാത്ത ചാർ *ബിൻ) ( struct elf32_hdr *PH = (struct pe_hdr *) (bin + *((അൺ സൈൻ ചെയ്യാത്ത നീളം *)&ബിൻ)); // തീർച്ചയായും, കോമ്പിനേഷൻ വ്യക്തമല്ല... dword എടുക്കുക ഓഫ്‌സെറ്റ് 0x3c // എന്നതിൽ PE ഹെഡറിന്റെ വിലാസം കണക്കാക്കുക, elf32_phdr *POH; എങ്കിൽ (PH == NULL || // പോയിന്റർ നിയന്ത്രിക്കുക PH->pe_sign != 0x4550 || // PE ഒപ്പ് (" P", "E", 0, 0) PH->pe_cputype != 0x14c || // i386 (PH->pe_flags & 2) == 0) // ഫയൽ റൺ ചെയ്യാൻ കഴിയില്ല! PE_WRONG തിരികെ നൽകുക; POH = (struct pe_ohdr *)((ഒപ്പ് ചെയ്യാത്ത ചാർ *)PH + 0xf8); അതേസമയം (PH->pe_obj_num--) (((POH->p_flags & 0x60) != 0) // ഒന്നുകിൽ കോഡ് അല്ലെങ്കിൽ ഇനീഷ്യലൈസ് ചെയ്ത ഡാറ്റ memcpy (PE->pe_image_base + POH->o_vaddr, bin + POH->o_poff, POH->o_psize); POH = (struct pe_ohdr *)((അൺസൈൻഡ് ചാർ *) POH + sizeof (struct pe_ohdr)); ) PE_OK മടങ്ങുക; )

ഇത് വീണ്ടും ഒരു റെഡിമെയ്ഡ് പ്രോഗ്രാമല്ല, മറിച്ച് ഒരു ലോഡിംഗ് അൽഗോരിതം ആണ്.

വീണ്ടും, വിഷയത്തിന്റെ പരിധിക്കപ്പുറത്തേക്ക് പോകുന്നതിനാൽ പല പോയിന്റുകളും ഉൾപ്പെടുത്തിയിട്ടില്ല.

എന്നാൽ ഇപ്പോൾ നിലവിലുള്ള സിസ്റ്റം സവിശേഷതകളെക്കുറിച്ച് കുറച്ച് സംസാരിക്കുന്നത് മൂല്യവത്താണ്.

സിസ്റ്റം സവിശേഷതകൾ.

പ്രൊസസറുകളിൽ (ഡിസ്ക്രിപ്റ്റർ ടേബിളുകളുടെ തലത്തിലുള്ള സംരക്ഷണം, സെഗ്മെന്റ് തലത്തിലുള്ള സംരക്ഷണം, പേജ് തലത്തിലുള്ള സംരക്ഷണം) ലഭ്യമായ സംരക്ഷണ ഉപകരണങ്ങളുടെ വഴക്കം ഉണ്ടായിരുന്നിട്ടും, നിലവിലുള്ള സിസ്റ്റങ്ങളിൽ (വിൻഡോസ്, യുണിക്സ് എന്നിവയിൽ) പേജ് സംരക്ഷണം മാത്രമേ പൂർണ്ണമായി ഉപയോഗിക്കുന്നുള്ളൂ, കോഡ് എഴുതുന്നതിൽ നിന്ന് ഇതിന് പരിരക്ഷിക്കാൻ കഴിയുമെങ്കിലും, എക്സിക്യൂഷനിൽ നിന്ന് ഡാറ്റ സംരക്ഷിക്കാൻ കഴിയില്ല. (സിസ്റ്റം കേടുപാടുകൾ ധാരാളമായി ഉണ്ടാകാനുള്ള കാരണം ഇതായിരിക്കാം?)

എല്ലാ സെഗ്‌മെന്റുകളും ലീനിയർ വിലാസ പൂജ്യത്തിൽ നിന്ന് അഭിസംബോധന ചെയ്യുകയും ലീനിയർ മെമ്മറിയുടെ അവസാനം വരെ നീട്ടുകയും ചെയ്യുന്നു. പേജ് ടേബിളുകളുടെ തലത്തിൽ മാത്രമാണ് പ്രോസസ്സ് ഡിലിമിറ്റേഷൻ നിർമ്മിച്ചിരിക്കുന്നത്.

ഇക്കാര്യത്തിൽ, എല്ലാ മൊഡ്യൂളുകളും ലിങ്ക് ചെയ്തിരിക്കുന്നത് ആരംഭ വിലാസങ്ങളിൽ നിന്നല്ല, മറിച്ച് സെഗ്‌മെന്റിൽ മതിയായ വലിയ ഓഫ്‌സെറ്റ് ഉപയോഗിച്ചാണ്. വിൻഡോസിൽ, സെഗ്മെന്റിലെ അടിസ്ഥാന വിലാസം 0x400000 ആണ്, യുണിക്സിൽ (ലിനക്സ് അല്ലെങ്കിൽ ഫ്രീബിഎസ്ഡി) - 0x8048000.

ചില സവിശേഷതകൾ മെമ്മറിയുടെ പേജ് ഓർഗനൈസേഷനുമായി ബന്ധപ്പെട്ടിരിക്കുന്നു.

വിഭാഗങ്ങളുടെ അതിരുകളും വലുപ്പങ്ങളും ഫയലിന്റെ 4 കിലോബൈറ്റ് ബ്ലോക്കുകൾക്കുള്ളിൽ വരുന്ന വിധത്തിലാണ് ELF ഫയലുകൾ ലിങ്ക് ചെയ്തിരിക്കുന്നത്.

PE ഫോർമാറ്റിൽ, 512 ബൈറ്റുകളുടെ വിഭാഗങ്ങൾ വിന്യസിക്കാൻ ഫോർമാറ്റ് തന്നെ നിങ്ങളെ അനുവദിക്കുന്നുണ്ടെങ്കിലും, വിഭാഗങ്ങളുടെ വിന്യാസം 4k-ൽ ഉപയോഗിക്കുന്നു; വിൻഡോസിലെ ഒരു ചെറിയ വിന്യാസം ശരിയായതായി കണക്കാക്കില്ല.

നല്ല TOC ഉം കൂടുതൽ ഉള്ളടക്കവും ഉള്ള ഈ ഉത്തരത്തിന്റെ പതിപ്പ്: http://www.cirosantilli.com/elf-hello-world (30k ചാർ പരിധിക്ക് ഇവിടെ ക്ലിക്ക് ചെയ്യുക)

മാനദണ്ഡങ്ങൾ

ELF നൽകുന്നത് LSB ആണ്:

  • കോർ ജനറിക്: http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/elf-generic.html
  • കോർ AMD64: http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-AMD64/LSB-Core-AMD64/book1.html

LSB പ്രധാനമായും ചെറിയ വിപുലീകരണങ്ങളുള്ള മറ്റ് മാനദണ്ഡങ്ങളെ സൂചിപ്പിക്കുന്നു, പ്രത്യേകിച്ചും:

    ജനറിക് (രണ്ടും SCO പ്രകാരം):

    • സിസ്റ്റം V ABI 4.1 (1997) http://www.sco.com/developers/devspecs/gabi41.pdf, 64 ബിറ്റ് അല്ല, അതിനായി ഒരു മാന്ത്രിക നമ്പർ റിസർവ് ചെയ്തിട്ടുണ്ടെങ്കിലും. പ്രധാന ഫയലുകളുടെ കാര്യവും ഇതുതന്നെ.
    • സിസ്റ്റം V ABI അപ്‌ഡേറ്റ് DRAFT 17 (2003) http://www.sco.com/developers/gabi/2003-12-17/contents.html 64 ബിറ്റുകൾ ചേർക്കുന്നു. മുമ്പത്തെ പ്രമാണത്തിന്റെ 4, 5 അധ്യായങ്ങൾ മാത്രം അപ്‌ഡേറ്റ് ചെയ്യുന്നു: ബാക്കിയുള്ളവ സാധുവായി തുടരുകയും ഇപ്പോഴും പരാമർശിക്കുകയും ചെയ്യുന്നു.
  • പ്രത്യേക വാസ്തുവിദ്യ:

    • IA-32: http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-IA32/LSB-Core-IA32/elf-ia32.html പോയിന്റുകൾ പ്രധാനമായും http://www.sco.com/developers / devspecs/abi386-4.pdf
    • AMD64: http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-AMD64/LSB-Core-AMD64/elf-amd64.html, പ്രധാനമായും പോയിന്റ് ചെയ്യുന്നത് http://www.x86-64.org/ ഡോക്യുമെന്റേഷനാണ് /abi.pdf

ഉപയോഗപ്രദമായ ഒരു ബയോഡാറ്റ ഇവിടെ കാണാം:

റീഡൽഫ്, ഒബ്ജ്ഡംപ് തുടങ്ങിയ ഉപയോക്തൃ-സൗഹൃദ രീതികൾ ഉപയോഗിച്ച് ഇതിന്റെ ഘടന പരിശോധിക്കാവുന്നതാണ്.

ഒരു ഉദാഹരണം സൃഷ്ടിക്കുക

ഒരു മിനിമൽ എക്സിക്യൂട്ടബിൾ Linux x86-64 ഉദാഹരണം വിഭജിക്കാം:

വിഭാഗം .ഡാറ്റ hello_world db "ഹലോ വേൾഡ്!", 10 hello_world_len equ $ - hello_world വിഭാഗം .ടെക്‌സ്റ്റ് ഗ്ലോബൽ _start _start: mov rax, 1 mov rdi, 1 mov rsi, hello_world mov rdx, molenvworldall6, molenv0_world സ്കാൾ

ഉപയോഗിച്ച് സമാഹരിച്ചത്

Nasm -w+all -f elf64 -o "hello_world.o" "hello_world.asm" ld -o "hello_world.out" "hello_world.o"

  • NASM 2.10.09
  • Binutils പതിപ്പ് 2.24 (ld അടങ്ങിയിരിക്കുന്നു)
  • ഉബുണ്ടു 14.04

ഞങ്ങൾ ഒരു സി പ്രോഗ്രാം ഉപയോഗിക്കുന്നില്ല, കാരണം ഇത് ലെവൽ 2 ആയിരിക്കുന്ന വിശകലനത്തെ സങ്കീർണ്ണമാക്കും :-)

ബൈനറിയുടെ ഹെക്സാഡെസിമൽ പ്രാതിനിധ്യം

hd hello_world.o hd hello_world.out

ആഗോള ഫയൽ ഘടന

ELF ഫയലിൽ ഇനിപ്പറയുന്ന ഭാഗങ്ങൾ അടങ്ങിയിരിക്കുന്നു:

  • ELF തലക്കെട്ട്. സെക്ഷൻ ഹെഡർ ടേബിളിന്റെയും പ്രോഗ്രാം ഹെഡർ ടേബിളിന്റെയും സ്ഥാനം സൂചിപ്പിക്കുന്നു.

    വിഭാഗം തലക്കെട്ട് പട്ടിക (എക്സിക്യൂട്ടബിൾ ഫയലിൽ ഓപ്ഷണൽ). അവയിൽ ഓരോന്നിനും സെക്ഷൻ ഹെഡറുകൾ e_shnum ഉണ്ട്, അവ ഓരോന്നും വിഭാഗത്തിന്റെ സ്ഥാനം സൂചിപ്പിക്കുന്നു.

    N ഉള്ള N പാർട്ടീഷനുകൾ N<= e_shnum (необязательно в исполняемом файле)

    പ്രോഗ്രാം ഹെഡർ ടേബിൾ (എക്സിക്യൂട്ടബിൾ ഫയലുകൾ മാത്രം). അവയിൽ ഓരോന്നിനും e_phnum പ്രോഗ്രാം ഹെഡറുകൾ ഉണ്ട്, അവ ഓരോന്നും സെഗ്മെന്റിന്റെ സ്ഥാനം സൂചിപ്പിക്കുന്നു.

    N സെഗ്‌മെന്റുകൾ, N ഉള്ളത്<= e_phnum (необязательно в исполняемом файле)

ഈ ഭാഗങ്ങളുടെ ക്രമം നിശ്ചയിച്ചിട്ടില്ല: സ്ഥിരമായ ഒരേയൊരു കാര്യം ELF തലക്കെട്ടാണ്, അത് ഫയലിൽ ആദ്യം വരണം: സാധാരണ ഡോക്‌സ് പറയുന്നു:

ELF തലക്കെട്ട്

തലക്കെട്ട് കാണാനുള്ള എളുപ്പവഴി ഇതാണ്:

റീഡൽഫ് -h hello_world.o readelf -h hello_world.out

ഒബ്‌ജക്റ്റ് ഫയലിലെ ബൈറ്റ്:

00000000 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 |.ELF............| 00000010 01 00 3e 00 01 00 00 00 00 00 00 00 00 00 00 00 |..>.............| 00000020 00 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 |........@......| 00000030 00 00 00 00 40 00 00 00 00 00 40 00 07 00 03 00 |....@.....@.....|

00000000 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 |.ELF............| 00000010 02 00 3e 00 01 00 00 00 b0 00 40 00 00 00 00 00 |..>......@.....| 00000020 40 00 00 00 00 00 00 00 10 01 00 00 00 00 00 00 |@............| 00000030 00 00 00 00 40 00 38 00 02 00 40 00 06 00 03 00 | [ഇമെയിൽ പരിരക്ഷിതം]...@.....|

അവതരിപ്പിച്ച ഘടന:

ടൈപ്പ്ഡെഫ് ഘടന ( ഒപ്പിടാത്ത ചാർ e_ident; Elf64_Half e_type; Elf64_Half e_machine; Elf64_Word e_version; Elf64_Addr e_entry; Elf64_Off e_phoff; Elf64_Off; Elf64_Off; Elf64_Off; 64_ഓഫ് പകുതി e_ehsize; Elf64_Half e_phent വലുപ്പം; Elf64_Half e_phnum; Elf64_Half e_shentsize; Elf64_Half e_shnum; Elf64_Half e_shstrndx; ) Elf64_Ehdr;

മാനുവൽ വിഘടനം:

    0 0: EI_MAG = 7f 45 4c 46 = 0x7f "E", "L", "F" : ELF മാജിക് നമ്പർ

    0 4: EI_CLASS=02=ELFCLASS64: 64-ബിറ്റ് എൽഫ്

    0 5: EI_DATA = 01 = ELFDATA2LSB: ബിഗ് എൻഡ് ഡാറ്റ

    0 6: EI_VERSION = 01: ഫോർമാറ്റ് പതിപ്പ്

    0 7: EI_OSABI (2003 മാത്രം) = 00 = ELFOSABI_NONE: വിപുലീകരണങ്ങളൊന്നുമില്ല.

    0 8: EI_PAD = 8x 00: റിസർവ് ചെയ്ത ബൈറ്റുകൾ. 0 ആയി സജ്ജീകരിക്കണം.

    1 0: e_type = 01 00 = 1 (ബിഗ് എൻഡിയൻ) = ET_REl: സ്ഥലം മാറ്റാവുന്ന ഫോർമാറ്റ്

    ET_EXEC-നുള്ള എക്സിക്യൂട്ടബിൾ ഫയലിൽ 02 00.

    1 2: e_machine = 3e 00 = 62 = EM_X86_64: AMD64 ആർക്കിടെക്ചർ

    1 4: e_version = 01 00 00 00: 1 ആയിരിക്കണം

    1 8: e_entry = 8x 00: എക്സിക്യൂഷൻ അഡ്രസ് എൻട്രി പോയിന്റ്, അല്ലെങ്കിൽ എൻട്രി പോയിന്റ് ഇല്ലാത്തതിനാൽ, ഒരു ഒബ്ജക്റ്റ് ഫയലിനെ സംബന്ധിച്ചിടത്തോളം ബാധകമല്ലെങ്കിൽ 0.

    എക്സിക്യൂട്ടബിൾ ഫയലിൽ ഇത് b0 00 40 00 00 00 00 00 ആണ്. TODO: നമുക്ക് മറ്റെന്താണ് ഇൻസ്റ്റാൾ ചെയ്യാൻ കഴിയുക? കേർണൽ ഈ മൂല്യത്തിലേക്ക് നേരിട്ട് IP ഇടുന്നതായി തോന്നുന്നു, ഇത് ഹാർഡ് കോഡ് ചെയ്തിട്ടില്ല.

    2 0: e_phoff = 8x 00: പ്രോഗ്രാം ഹെഡർ ടേബിൾ ഓഫ്‌സെറ്റ്, ഒന്നുമില്ലെങ്കിൽ 0.

    എക്സിക്യൂട്ടബിളിൽ 40 00 00 00, അതായത് ELF ഹെഡറിന് തൊട്ടുപിന്നാലെ അത് ആരംഭിക്കുന്നു.

    2 8: e_shoff = 40 7x 00 = 0x40: സെക്ഷൻ ഹെഡർ ടേബിൾ ഫയലിന്റെ ഓഫ്‌സെറ്റ്, ഒന്നുമില്ലെങ്കിൽ 0.

    3 0: e_flags = 00 00 00 00 TODO. പ്രത്യേകിച്ച് ആർക്കിന്.

    3 4: e_ehsize = 40 00: ഈ എൽഫ് ഹെഡറിന്റെ വലുപ്പം. എന്തുകൊണ്ടാണ് ഈ ഫീൽഡ്? ഇത് എങ്ങനെ മാറും?

    3 6: e_phentsize = 00 00: ഓരോ പ്രോഗ്രാം ഹെഡറിന്റെയും വലിപ്പം, ഒന്നുമില്ലെങ്കിൽ 0.

    എക്സിക്യൂട്ടബിൾ ഫയലിൽ 38 00: ഫയൽ ദൈർഘ്യം 56 ബൈറ്റുകൾ ആണ്

    3 8: e_phnum = 00 00: പ്രോഗ്രാം ഹെഡർ എൻട്രികളുടെ എണ്ണം, ഒന്നുമില്ലെങ്കിൽ 0.

    എക്സിക്യൂട്ടബിൾ ഫയലിൽ 02 00: 2 എൻട്രികൾ ഉണ്ട്.

    3 എ: e_shentsize, e_shnum = 40 00 07 00: സെക്ഷൻ ഹെഡർ വലുപ്പവും എൻട്രികളുടെ എണ്ണവും

വിഭാഗം തലക്കെട്ട് പട്ടിക

Elf64_Shdr ഘടനകളുടെ നിര.

ഓരോ എൻട്രിയിലും ആ വിഭാഗത്തെക്കുറിച്ചുള്ള മെറ്റാഡാറ്റ അടങ്ങിയിരിക്കുന്നു.

ELF ഹെഡർ e_shoff ഇവിടെ ആരംഭ സ്ഥാനം നൽകുന്നു, 0x40.

ELF ഹെഡറിൽ നിന്നുള്ള e_shentsize, e_shnum എന്നിവ പറയുന്നത് ഞങ്ങൾക്ക് 7 എൻട്രികൾ ഉണ്ടെന്ന് പറയുന്നു, ഓരോന്നിനും 0x40 നീളമുണ്ട്.

അതിനാൽ പട്ടിക 0x40 മുതൽ 0x40 + 7 + 0x40 - 1 = 0x1FF വരെയുള്ള ബൈറ്റുകൾ എടുക്കുന്നു.

ചില വിഭാഗ ശീർഷകങ്ങൾ ചില വിഭാഗങ്ങൾക്കായി നീക്കിവച്ചിരിക്കുന്നു: http://www.sco.com/developers/gabi/2003-12-17/ch4.sheader.html#special_sections, ഉദാഹരണത്തിന്. .ടെക്‌സ്റ്റിന് SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR എന്നിവ ആവശ്യമാണ്

readelf -S hello_world.o:

ഓഫ്‌സെറ്റ് 0x40 മുതൽ ആരംഭിക്കുന്ന 7 സെക്ഷൻ ഹെഡറുകൾ ഉണ്ട്: സെക്ഷൻ ഹെഡറുകൾ: പേര് തരം വിലാസം ഓഫ്‌സെറ്റ് സൈസ് എൻറ്റ്‌സൈസ് ഫ്ലാഗുകൾ ലിങ്ക് വിവരങ്ങൾ വിന്യസിക്കുക [ 0] NULL 0000000000000000 00000000 000000000000000000000000000 1].data PROGBITS 0 000000000000000000002000000000[2] .ടെക്സ്റ്റ് പ്രോജിബിറ്റുകൾ 000000000000000000000210 000000000000027 00000000000000016 [3].shst00 00000000032 0000000000000000 0 0 1 [4].symtab SYMTAB 000000000000000 000002800000000000000000000000000000000STRTAB 000000000000000 00000330 0000000000000034 0000000000000000 0 0 1 [ 6].rela.text RELA 000000000000000 00000370 0000000000000018 0000000000000018 00000000000000018 ute), M (ലയിപ്പിക്കുക), S (സ്ട്രിംഗുകൾ), l ( വലുത്) I (വിവരങ്ങൾ), L (ലിങ്ക് ഓർഡർ), G (ഗ്രൂപ്പ്), T (TLS), E (ഒഴിവാക്കുക), x (അജ്ഞാതം) O (അധിക OS പ്രോസസ്സിംഗ് ആവശ്യമാണ്) o (OS സ്പെസിഫിക്), p (പ്രോസസർ നിർദ്ദിഷ്ടം)

ഓരോ എൻട്രിയും പ്രതിനിധീകരിക്കുന്ന ഘടന:

ടൈപ്പ്ഡെഫ് ഘടന (Elf64_Word sh_name; Elf64_Word sh_type; Elf64_Xword sh_flags; Elf64_Addr sh_addr; Elf64_Off sh_offset; Elf64_Xword sh_link; Elf64_Xword sh_link; Elf64_Xword sh_link; Elf664 4_Xword sh_addralign; Elf64_X വാക്ക് sh_entsize; ) Elf64_Shdr;

വിഭാഗങ്ങൾ

സൂചിക വിഭാഗം 0

0x40 മുതൽ 0x7F വരെയുള്ള ബൈറ്റുകളിൽ അടങ്ങിയിരിക്കുന്നു.

ആദ്യ വിഭാഗം എപ്പോഴും മാന്ത്രികമാണ്: http://www.sco.com/developers/gabi/2003-12-17/ch4.sheader.html പറയുന്നു:

പാർട്ടീഷനുകളുടെ എണ്ണം SHN_LORESERVE (0xff00) നേക്കാൾ വലുതോ തുല്യമോ ആണെങ്കിൽ, e_shnum എന്നത് SHN_UNDEF (0) ആയി സജ്ജീകരിക്കും, കൂടാതെ പാർട്ടീഷൻ ഹെഡർ ടേബിൾ എൻട്രികളുടെ യഥാർത്ഥ എണ്ണം ഇൻഡെക്സ് 0-ൽ പാർട്ടീഷൻ ഹെഡറിന്റെ sh_size ഫീൽഡിൽ അടങ്ങിയിരിക്കുന്നു (അല്ലെങ്കിൽ പ്രാരംഭ എൻട്രിയുടെ sh_size അംഗത്തിൽ 0 അടങ്ങിയിരിക്കുന്നു).

ചിത്രം 4-7 ൽ മറ്റ് മാജിക് വിഭാഗങ്ങളുണ്ട്: പ്രത്യേക വിഭാഗം സൂചികകൾ.

സൂചിക 0-ൽ, SHT_NULL ആവശ്യമാണ്. ഇതിന് മറ്റ് ഉപയോഗങ്ങളുണ്ടോ: ELF-ലെ SHT_NULL വിഭാഗത്തിന്റെ ഉപയോഗം എന്താണ്? ?

.ഡാറ്റ വിഭാഗം

ഡാറ്റ വിഭാഗം 1 ആണ്:

00000080 01 00 00 00 01 00 00 00 03 00 00 00 00 00 00 00 |............| 00000090 00 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 |...........| 000000a0 0d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |............| 000000b0 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |...........|

    ഇവിടെ 1 പറയുന്നത്, ഈ വിഭാഗത്തിന്റെ പേര് ഈ വിഭാഗത്തിന്റെ ആദ്യ പ്രതീകത്തിൽ ആരംഭിക്കുകയും ആദ്യത്തെ NUL പ്രതീകത്തിൽ അവസാനിക്കുകയും ചെയ്യുന്നു, ഇത് string.data ഉണ്ടാക്കുന്നു.

    http://www.sco.com/developers/gabi/2003-12-17/ch4.strtab.html മുൻകൂട്ടി നിശ്ചയിച്ച അർത്ഥമുള്ള വിഭാഗ നാമങ്ങളിൽ ഒന്നാണ് ഡാറ്റ

    പ്രോഗ്രാമിന്റെ മെമ്മറി ഇമേജിലേക്ക് സംഭാവന ചെയ്യുന്ന പ്രാരംഭ ഡാറ്റ ഈ വിഭാഗങ്ങൾ സംഭരിക്കുന്നു.

  • 80 4: sh_type = 01 00 00 00: SHT_PROGBITS: വിഭാഗത്തിലെ ഉള്ളടക്കങ്ങൾ ELF വ്യക്തമാക്കിയിട്ടില്ല, പ്രോഗ്രാം എങ്ങനെ വ്യാഖ്യാനിക്കുന്നു എന്നതിലൂടെ മാത്രം. ശരി, ഒരു .ഡാറ്റ മുതൽ .

    80 8: sh_flags = 03 7x 00: SHF_ALLOC, SHF_EXECINSTR: http://www.sco.com/developers/gabi/2003-12-17/ch4.sheader.html#sh_flags .ഡാറ്റ വിഭാഗത്തിൽ നിന്ന്

    90 0: sh_addr = 8x 00: ഏത് വെർച്വൽ വിലാസത്തിലാണ് പാർട്ടീഷൻ റൺടൈമിൽ സ്ഥാപിക്കുന്നത്, 0 സ്ഥാപിച്ചിട്ടില്ലെങ്കിൽ

    90 8: sh_offset = 00 02 00 00 00 00 00 00 = 0x200: പ്രോഗ്രാമിന്റെ തുടക്കം മുതൽ ഈ വിഭാഗത്തിലെ ആദ്യ ബൈറ്റ് വരെയുള്ള ബൈറ്റുകളുടെ എണ്ണം

    a0 0: sh_size = 0d 00 00 00 00 00 00 00

    sh_offset 200 മുതൽ 0xD ബൈറ്റുകൾ എടുക്കുകയാണെങ്കിൽ, നമ്മൾ കാണുന്നത്:

    00000200 48 65 6c 6c 6f 20 77 6f 72 6c 64 21 0a 00 |ഹലോ വേൾഡ്!.. |

    ആഹാ! അതിനാൽ ഞങ്ങളുടെ സ്ട്രിംഗ് "ഹലോ വേൾഡ്!" ഡാറ്റാ വിഭാഗത്തിലാണ്, ഞങ്ങൾ പറഞ്ഞതുപോലെ, ഇത് NASM-ലാണ്.

    ഞങ്ങൾ എച്ച്ഡി പൂർത്തിയാക്കിക്കഴിഞ്ഞാൽ, ഞങ്ങൾ ഇത് ഇതുപോലെ നോക്കും:

    Readelf -x .data hello_world.o

    ഏത് ഔട്ട്പുട്ടുകൾ:

    ".ഡാറ്റ" വിഭാഗത്തിന്റെ ഹെക്സ് ഡംപ്: 0x00000000 48656c6c 6f20776f 726c6421 0a ഹലോ വേൾഡ്!.

    NASM ഈ വിഭാഗത്തിന് മാന്യമായ പ്രോപ്പർട്ടികൾ സജ്ജമാക്കുന്നു, കാരണം ഇത് .ഡാറ്റയെ മാന്ത്രികമായി പരാമർശിക്കുന്നു: http://www.nasm.us/doc/nasmdoc7.html#section-7.9.2

    ഈ വിഭാഗത്തിന്റെ തെറ്റായ തിരഞ്ഞെടുപ്പാണിത് എന്നതും ശ്രദ്ധിക്കുക: ഒരു നല്ല സി കംപൈലർ .റോഡാറ്റയിൽ സ്ട്രിംഗ് ഇടുമായിരുന്നു, കാരണം ഇത് റീഡ്-ഒൺലി ആയതിനാൽ ഇത് കൂടുതൽ OS ഒപ്റ്റിമൈസേഷൻ അനുവദിക്കും.

    a0 8: sh_link, sh_info = 8x 0: ഈ വിഭാഗത്തിന്റെ തരത്തിന് ബാധകമല്ല. http://www.sco.com/developers/gabi/2003-12-17/ch4.sheader.html#special_sections

    b0 0: sh_addralign = 04 = TODO: എന്തുകൊണ്ട് ഈ വിന്യാസം ആവശ്യമാണ്? ഇത് sh_addr നും sh_addr-നുള്ളിലെ പ്രതീകങ്ങൾക്കും മാത്രമാണോ?

    b0 8: sh_entsize = 00 = പാർട്ടീഷനിൽ ഒരു പട്ടിക അടങ്ങിയിട്ടില്ല. != 0 ആണെങ്കിൽ, പാർട്ടീഷനിൽ നിശ്ചിത വലുപ്പത്തിലുള്ള എൻട്രികളുടെ ഒരു പട്ടിക അടങ്ങിയിരിക്കുന്നു എന്നാണ് ഇതിനർത്ഥം. ഈ ഫയലിൽ, .symtab, .rela.text എന്നീ വിഭാഗങ്ങളുടെ കാര്യം ഇതാണ് എന്ന് റീഡൽഫ് ഔട്ട്പുട്ടിൽ നിന്ന് നമുക്ക് കാണാം.

.ടെക്സ്റ്റ് വിഭാഗം

ഇപ്പോൾ ഞങ്ങൾ ഒരു വിഭാഗം സ്വമേധയാ ചെയ്തുകഴിഞ്ഞു, നമുക്ക് ബിരുദം നേടാം, മറ്റ് വിഭാഗങ്ങളിൽ റീഡൽഫ് -S ഉപയോഗിക്കുക.

പേര് തരം വിലാസം ഓഫ്‌സെറ്റ് സൈസ് എൻറ്റ്‌സൈസ് ഫ്ലാഗുകൾ ലിങ്ക് വിവരങ്ങൾ വിന്യസിക്കുക [2].ടെക്‌സ്റ്റ് പ്രോജിബിറ്റ്‌സ് 000000000000000 00000210 000000000000027 000000000000000000000000000000

ടെക്‌സ്‌റ്റ് എക്‌സിക്യൂട്ടബിൾ ആണ്, പക്ഷേ എഴുതാൻ കഴിയില്ല: നമ്മൾ അതിലേക്ക് എഴുതാൻ ശ്രമിക്കുകയാണെങ്കിൽ Linux segfaults. നമുക്ക് ശരിക്കും കോഡ് ഉണ്ടോ എന്ന് നോക്കാം:

Objdump -d hello_world.o

Hello_world.o: ഫയൽ ഫോർമാറ്റ് elf64-x86-64 വിഭാഗത്തിന്റെ ഡിസ്അസംബ്ലിംഗ് .ടെക്സ്റ്റ്: 0000000000000000<_start>: 0: b8 01 00 00 00 mov $0x1,%eax 5: bf 01 00 00 00 mov $0x1,%edi a: 48 be 00 00 00 00 00 movabs $0x0,%rsi 11: 00 10 0d 00 00 00 mov $0xd,%edx 19: 0f 05 syscall 1b: b8 3c 00 00 00 mov $0x3c,%eax 20: bf 00 00 00 00 mov $0x0,% 0fsc 25

നമുക്ക് hd-ൽ grep b8 01 00 00 ഉണ്ടെങ്കിൽ, അത് 00000210-ൽ മാത്രമേ സംഭവിക്കുകയുള്ളൂ എന്ന് ഞങ്ങൾ കാണുന്നു, അതാണ് ഈ വിഭാഗം പറയുന്നത്. വലിപ്പം 27 ആണ്, അതും യോജിക്കുന്നു. അതിനാൽ, നമ്മൾ ശരിയായ വിഭാഗത്തെക്കുറിച്ച് സംസാരിക്കണം.

ഇത് ശരിയായ കോഡ് പോലെ കാണപ്പെടുന്നു: ഒരു എഴുത്ത് തുടർന്ന് എക്സിറ്റ് .

ഏറ്റവും രസകരമായ ഭാഗം ഒരു വരിയാണ്, അത് ചെയ്യുന്നു:

Movabs $0x0,%rsi

സിസ്റ്റം കോളിലേക്ക് സ്ട്രിംഗിന്റെ വിലാസം കൈമാറുക. നിലവിൽ 0x0 എന്നത് ഒരു പ്ലെയ്‌സ്‌ഹോൾഡർ മാത്രമാണ്. ബന്ധിപ്പിച്ചതിന് ശേഷം ഇത് മാറും:

4000ba: 48 be d8 00 60 00 00 movabs $0x6000d8,%rsi

data.rela.text എന്ന വിഭാഗം കാരണം ഈ പരിഷ്‌ക്കരണം സാധ്യമാണ്.

SHT_STRTAB

sh_type == SHT_STRTAB ഉള്ള പാർട്ടീഷനുകളെ സ്ട്രിംഗ് ടേബിളുകൾ എന്ന് വിളിക്കുന്നു.

സ്ട്രിംഗ് നാമങ്ങൾ ഉപയോഗിക്കേണ്ടിവരുമ്പോൾ അത്തരം വിഭാഗങ്ങൾ മറ്റ് വിഭാഗങ്ങൾ ഉപയോഗിക്കുന്നു. ഉപയോഗ വിഭാഗം പറയുന്നു:

  • അവർ എന്ത് സ്ട്രിംഗാണ് ഉപയോഗിക്കുന്നത്
  • വരി ആരംഭിക്കുന്ന ടാർഗെറ്റ് വരി പട്ടികയിലെ സൂചിക എന്താണ്

അതിനാൽ, ഉദാഹരണത്തിന്, നമുക്ക് ഇനിപ്പറയുന്നവ ഉൾക്കൊള്ളുന്ന ഒരു സ്ട്രിംഗ് ടേബിൾ ഉണ്ടായിരിക്കാം: TODO: നമ്മൾ \0 എന്ന് തുടങ്ങണോ?

ഡാറ്റ: \0 a b c \0 d e f \0 സൂചിക: 0 1 2 3 4 5 6 7 8

മറ്റൊരു വിഭാഗത്തിന് d e f എന്ന വരി ഉപയോഗിക്കണമെങ്കിൽ, അവർ ആ വിഭാഗത്തിന്റെ സൂചിക 5-ലേക്ക് പോയിന്റ് ചെയ്യണം (അക്ഷരം d).

അറിയപ്പെടുന്ന സ്ട്രിംഗ് പട്ടികകൾ:

  • .shstrtab
  • .strtab

.shstrtab

വിഭാഗം തരം: sh_type == SHT_STRTAB .

പൊതുവായ പേര്: സെക്ഷൻ ഹെഡർ ടൈറ്റിൽ ലൈൻ.

വിഭാഗം name.shstrtab സംവരണം ചെയ്തിരിക്കുന്നു. സ്റ്റാൻഡേർഡ് പറയുന്നു:

ഈ വിഭാഗത്തിൽ വിഭാഗങ്ങളുടെ പേരുകൾ അടങ്ങിയിരിക്കുന്നു.

ഈ വിഭാഗം ELF ഹെഡറിന്റെ തന്നെ e_shstrnd ഫീൽഡ് വ്യക്തമാക്കുന്നു.

ഈ വിഭാഗത്തിന്റെ വരി സൂചികകൾ വരികളെ പ്രതിനിധീകരിക്കുന്ന സെക്ഷൻ ഹെഡറുകളുടെ sh_name ഫീൽഡ് സൂചിപ്പിക്കുന്നു.

ഈ വിഭാഗത്തിൽ SHF_ALLOC വ്യക്തമാക്കിയിട്ടില്ല, അതിനാൽ ഇത് എക്സിക്യൂട്ടബിൾ പ്രോഗ്രാമിൽ ദൃശ്യമാകില്ല.

Readelf -x .shstrtab hello_world.o

".shstrtab" എന്ന വിഭാഗത്തിന്റെ ഹെക്‌സ് ഡംപ്: 0x00000000 002e6461 7461002e 74657874 002e7368 ..data..text..sh 0x00000010 73747274 616720010 73747270 61672066167206 ymt ab.. 0x00000020 73747274 6162002e 72656c61 2e746578 strtab..rela.tex 0x00000030 7400 ടി.

ഈ വിഭാഗത്തിലെ ഡാറ്റ ഒരു നിശ്ചിത ഫോർമാറ്റിലാണ്: http://www.sco.com/developers/gabi/2003-12-17/ch4.strtab.html

മറ്റ് വിഭാഗങ്ങളുടെ പേരുകൾ പരിശോധിച്ചാൽ, അവയിലെല്ലാം അക്കങ്ങൾ അടങ്ങിയിരിക്കുന്നതായി കാണാം, ഉദാ. section.text 7 എന്ന നമ്പറിലാണ്.

ആദ്യ NUL പ്രതീകം കണ്ടെത്തുമ്പോൾ ഓരോ വരിയും അവസാനിക്കുന്നു, ഉദാഹരണത്തിന്. അക്ഷരം 12 \0 ഉടൻ .ടെക്സ്റ്റ്\0 .

.സിംടാബ്

വിഭാഗം തരം: sh_type == SHT_SYMTAB .

പൊതുവായ പേര്: ചിഹ്ന പട്ടിക.

ആദ്യം നമുക്ക് ഇത് ശ്രദ്ധിക്കാം:

  • sh_link = 5
  • sh_info = 6

SHT_SYMTAB വിഭാഗത്തിൽ ഈ സംഖ്യകൾ അർത്ഥമാക്കുന്നത്:

  • സ്ട്രിംഗുകൾ
  • ചിഹ്ന നാമങ്ങൾ നൽകുന്ന വിഭാഗങ്ങൾ 5, .strtab
  • ചലന ഡാറ്റ വിഭാഗം 6, .rela.text-ലാണ്

ഈ വിഭാഗം ഡിസ്അസംബ്ലിംഗ് ചെയ്യുന്നതിനുള്ള നല്ല ഉയർന്ന തലത്തിലുള്ള ഉപകരണം:

Nm hello_world.o

ഇത് നൽകുന്നു:

0000000000000000 T_start 000000000000000 d hello_world 000000000000000d a hello_world_len

എന്നിരുന്നാലും, ഇത് ചില പ്രതീക തരങ്ങളെ ഒഴിവാക്കുന്ന ഒരു ഉയർന്ന തലത്തിലുള്ള പ്രാതിനിധ്യമാണ്, അതിൽ പ്രതീകങ്ങൾ നിയുക്തമാക്കിയിരിക്കുന്നു. കൂടുതൽ വിശദമായ ഡിസ്അസംബ്ലിംഗ് ഇനിപ്പറയുന്നവ ഉപയോഗിച്ച് ലഭിക്കും:

റീഡൽഫ് -s hello_world.o

ഇത് നൽകുന്നു:

ചിഹ്ന പട്ടിക ".symtab"-ൽ 7 എൻട്രികൾ അടങ്ങിയിരിക്കുന്നു: സംഖ്യ: മൂല്യത്തിന്റെ വലിപ്പം ടൈപ്പ് ബൈൻഡ് വിസ് Ndx പേര് 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND 1: 00000000000000000000000 000000000000 0 വിഭാഗം ലോക്കൽ ഡിഫോൾട്ട് 1 3: 00000000000000000 0 വിഭാഗം ലോക്കൽ ഡിഫോൾട്ട് 2 4: 0000000000000000 0 നോട്ട്പി ലോക്കൽ ഡിഫോൾട്ട് 1 hello_world 5: 000000000000000d 0 NOTYPE LOCAL DEFAULT ABS0000000000000000000000 PE GLOBAL DEFAULT 2 _start

പട്ടികയുടെ ബൈനറി ഫോർമാറ്റ് http://www.sco.com/developers/gabi/2003-12-17/ch4.symtab.html എന്നതിൽ രേഖപ്പെടുത്തിയിട്ടുണ്ട്

Readelf -x .symtab hello_world.o

എന്താണ് നൽകുന്നത്:

".symtab" എന്ന വിഭാഗത്തിന്റെ ഹെക്‌സ് ഡംപ്: 0x00000000 00000000 00000000 00000000 00000000 ................ 0x00000010 00000000 00000000 01000 01000 0100 0x00000020 00000000 00000000 00000000 00000000 ................ 0x00000030 00000000 03000100 00000000 00000000000000000 0000 00000000 03000200 .. .............. 0x00000050 00000000 00000000 00000000 00000000 ................ 0x00000060 11000000 00000100 00000000 000000 000000 ..... 0x00000070 00000000 00000000 1d000000 0000f1ff ................ 0x00000080 0d000000 00000000 0000000 00000000 00000000 00000000000000000 0200 00000000 00000000 -............... 0x000000a0 00000000 00000000 ........

രേഖകൾ ഇപ്രകാരമാണ്:

ടൈപ്പ്ഡെഫ് ഘടന (Elf64_Word st_name; ഒപ്പിടാത്ത char st_info; ഒപ്പിടാത്ത char st_other; Elf64_Half st_shndx; Elf64_Addr st_value; Elf64_Xword st_size; ) Elf64_Sym;

പാർട്ടീഷൻ ടേബിൾ പോലെ, ആദ്യ എൻട്രി മാജിക് ആണ്, കൂടാതെ സ്ഥിരവും അർത്ഥമില്ലാത്തതുമായ മൂല്യങ്ങൾ നൽകിയിരിക്കുന്നു.

റെക്കോർഡ് 1 ന് ELF64_R_TYPE == STT_FILE ഉണ്ട്. ELF64_R_TYPE st_info-ൽ തുടരുന്നു.

ബൈറ്റ് വിശകലനം:

    10 8: st_name = 01000000 = .strtab ലെ പ്രതീകം 1 അത് അടുത്ത \0 ന് മുമ്പ് hello_world.asm ആക്കുന്നു

    ഏത് സെഗ്‌മെന്റ് സെഗ്‌മെന്റാണ് പോകുന്നതെന്ന് നിർണ്ണയിക്കാൻ ലിങ്കറിന് ഈ വിവര ഫയലിന്റെ ഭാഗം ഉപയോഗിക്കാം.

    10 12: st_info = 04

    ബിറ്റുകൾ 0-3 = ELF64_R_TYPE = തരം = 4 = STT_FILE: ഈ ഒബ്‌ജക്റ്റ് ഫയൽ സൃഷ്ടിച്ച ഫയലിന്റെ പേര് സൂചിപ്പിക്കാൻ st_name ഉപയോഗിക്കുക എന്നതാണ് ഈ എൻട്രിയുടെ പ്രധാന ലക്ഷ്യം.

    ബിറ്റുകൾ 4-7 = ELF64_ST_BIND = ബൈൻഡിംഗ് = 0 = STB_LOCAL . STT_FILE എന്നതിന് ആവശ്യമായ മൂല്യം.

    10 13: st_shndx = ചിഹ്ന പട്ടിക തലക്കെട്ട് പട്ടിക സൂചിക = f1ff = SHN_ABS . STT_FILE-ന് ആവശ്യമാണ്.

    20 0: st_value = 8x 00: STT_FILE-നുള്ള മൂല്യത്തിന് ആവശ്യമാണ്

    20 8: st_size = 8x 00: അനുവദിച്ച വലുപ്പമില്ല

ഇപ്പോൾ വായനയിൽ നിന്ന് ഞങ്ങൾ ബാക്കിയുള്ളവ വേഗത്തിൽ വ്യാഖ്യാനിക്കും.

STT_SECTION

അത്തരത്തിലുള്ള രണ്ട് ഘടകങ്ങളുണ്ട്, ഒന്ന് .ഡാറ്റയിലേക്കും മറ്റൊന്ന് .ടെക്‌സ്റ്റിലേക്കും ചൂണ്ടിക്കാണിക്കുന്നു (വിഭാഗ സൂചികകൾ 1, 2).

നമ്പർ: മൂല്യ വലുപ്പ തരം ബൈൻഡ് വിസ് Ndx പേര് 2: 000000000000000 0 വിഭാഗം ലോക്കൽ ഡിഫോൾട്ട് 1 3: 0000000000000000 0 വിഭാഗം ലോക്കൽ ഡിഫോൾട്ട് 2

TODO, എന്താണ് അവരുടെ ഉദ്ദേശം?

STT_NOTYPE

തുടർന്ന് ഏറ്റവും പ്രധാനപ്പെട്ട പ്രതീകങ്ങൾ നൽകുക:

നമ്പർ: മൂല്യ വലുപ്പ തരം ബൈൻഡ് വിസ് Ndx പേര് 4: 000000000000000 0 NOTYPE ലോക്കൽ ഡിഫാൾട്ട് 1 hello_world 5: 000000000000000d 0 NOTYPE LOCAL DEFAULT 000000000000000000000 0 നോട്ടൈപ്പ് ഗ്ലോബൽ ഡിഫോൾട്ട് 2 _സ്റ്റാർട്ട് സ്ട്രിംഗ്

hello_world.data വിഭാഗത്തിലാണ് (ഇൻഡക്സ് 1). ഈ മൂല്യം 0 ആണ്: ഇത് ഈ വിഭാഗത്തിന്റെ ആദ്യ ബൈറ്റിലേക്ക് പോയിന്റ് ചെയ്യുന്നു.

ഞങ്ങൾ എഴുതിയതിനാൽ ആരംഭം ആഗോള ദൃശ്യപരത കൊണ്ട് അടയാളപ്പെടുത്തിയിരിക്കുന്നു:

Global_start

NASM-ൽ. ഇത് ഒരു പ്രവേശന പോയിന്റായി കണക്കാക്കേണ്ടതിനാൽ ഇത് ആവശ്യമാണ്. സിയിൽ നിന്ന് വ്യത്യസ്തമായി, NASM ലേബലുകൾ സ്ഥിരസ്ഥിതിയായി പ്രാദേശികമാണ്.

hello_world_len പ്രത്യേക st_shndx == SHN_ABS == 0xF1FF ലേക്ക് പോയിന്റ് ചെയ്യുന്നു.

മറ്റ് വിഭാഗങ്ങളുമായി വൈരുദ്ധ്യമുണ്ടാകാതിരിക്കാൻ 0xF1FF തിരഞ്ഞെടുത്തു.

st_value == 0xD == 13 ഞങ്ങൾ അവിടെ അസംബ്ലിയിൽ സംഭരിച്ച മൂല്യമാണ്: സ്ട്രിംഗിന്റെ നീളം ഹലോ വേൾഡ്! .

ചലനം ഈ മൂല്യത്തെ ബാധിക്കില്ല എന്നാണ് ഇതിനർത്ഥം: ഇത് ഒരു സ്ഥിരാങ്കമാണ്.

ഇത് ഞങ്ങളുടെ അസംബ്ലർ ഞങ്ങൾക്കായി ചെയ്യുന്ന ഒരു ചെറിയ ഒപ്റ്റിമൈസേഷനാണ് കൂടാതെ ELF പിന്തുണയും ഉണ്ട്.

ഞങ്ങൾ എവിടെയെങ്കിലും hello_world_len വിലാസം ഉപയോഗിച്ചിട്ടുണ്ടെങ്കിൽ, അസംബ്ലർക്ക് അത് SHN_ABS ആയി അടയാളപ്പെടുത്താൻ കഴിയില്ല, കൂടാതെ ലിങ്കറിന് പിന്നീട് അധിക സ്ഥലംമാറ്റം ഉണ്ടാകും.

എക്സിക്യൂട്ടബിളിൽ SHT_SYMTAB

സ്ഥിരസ്ഥിതിയായി, എക്സിക്യൂട്ടബിൾ ഫയലിൽ NASM .symtab സ്ഥാപിക്കുന്നു.

ഇത് ഡീബഗ്ഗിംഗ് ആവശ്യങ്ങൾക്ക് മാത്രമാണ് ഉപയോഗിക്കുന്നത്. ചിഹ്നങ്ങളില്ലാതെ നമ്മൾ പൂർണ്ണമായും അന്ധരാണ്, എല്ലാം റിവേഴ്സ് എഞ്ചിനീയർ ചെയ്യണം.

objcopy ഉപയോഗിച്ച് നിങ്ങൾക്ക് ഇത് നീക്കംചെയ്യാം, എക്സിക്യൂട്ടബിൾ ഇപ്പോഴും പ്രവർത്തിക്കും. അത്തരം എക്സിക്യൂട്ടബിളുകളെ സ്പ്ലിറ്റ് എക്സിക്യൂട്ടബിളുകൾ എന്ന് വിളിക്കുന്നു.

.strtab

ഒരു ചിഹ്ന പട്ടികയ്ക്കായി സ്ട്രിംഗുകൾ പിടിക്കുന്നു.

ഈ വിഭാഗത്തിൽ sh_type == SHT_STRTAB .

sh_link == 5 section.symtab ലേക്ക് ചൂണ്ടിക്കാണിച്ചു.

Readelf -x .strtab hello_world.o

".strtab" എന്ന വിഭാഗത്തിന്റെ ഹെക്‌സ് ഡംപ്: 0x00000000 0068656c 6c6f5f77 6f726c64 2e61736d .hello_world.asm 0x00000010 0068656c 76c6fellow676fellow606fello5 ld.hel 0x00000020 6c6f5f77 6f726c64 5f6c656e 005f7374 lo_world_len._st 0x00000030 61727400 ആർട്ട്.

ഗ്ലോബൽ വേരിയബിളുകളിൽ NUL പ്രതീകങ്ങൾ ഉൾക്കൊള്ളാൻ കഴിയില്ല എന്നത് ELF ലെവൽ പരിമിതി എന്നാണ് ഇതിനർത്ഥം.

.rela.text

വിഭാഗം തരം: sh_type == SHT_RELA .

പൊതുനാമം: നീക്കം വിഭാഗം.

അവസാനമായി എക്സിക്യൂട്ടബിൾ ലിങ്ക് ചെയ്യുമ്പോൾ വിലാസം എങ്ങനെ മാറ്റണം എന്ന് വ്യക്തമാക്കുന്ന സ്ഥലമാറ്റ ഡാറ്റ Rela.text-ൽ അടങ്ങിയിരിക്കുന്നു. ശരിയായ മെമ്മറി ലൊക്കേഷനുകളിലേക്ക് ബൈൻഡിംഗ് സംഭവിക്കുമ്പോൾ മാറ്റേണ്ട ടെക്സ്റ്റ് ഏരിയ ബൈറ്റുകളിലേക്ക് ഇത് ചൂണ്ടിക്കാണിക്കുന്നു.

അടിസ്ഥാനപരമായി, ഇത് 0x0 പ്ലെയ്‌സ്‌ഹോൾഡറിന്റെ വിലാസം അടങ്ങിയ ഒബ്‌ജക്റ്റിന്റെ വാചകം പരിവർത്തനം ചെയ്യുന്നു:

A: 48 be 00 00 00 00 00 movabs $0x0,%rsi 11: 00 00 00

അന്തിമ 0x6000d8 അടങ്ങുന്ന യഥാർത്ഥ എക്സിക്യൂട്ടബിൾ കോഡിലേക്ക്:

4000ba: 48 be d8 00 60 00 00 movabs $0x6000d8,%rsi 4000c1: 00 00 00

sh_info = 6 sections.symtab വ്യക്തമാക്കിയിട്ടുണ്ട്.

readelf -r hello_world.o നൽകുന്നു:

ഓഫ്‌സെറ്റ് 0x3b0 ലെ റീലോക്കേഷൻ വിഭാഗം ".rela.text" 1 എൻട്രികൾ ഉൾക്കൊള്ളുന്നു: ഓഫ്‌സെറ്റ് വിവര തരം സിം. മൂല്യ സിം. പേര് + കൂട്ടിച്ചേർക്കൽ 00000000000c 000200000001 R_X86_64_64 000000000000000 .ഡാറ്റ + 0

എക്സിക്യൂട്ടബിളിൽ ഈ വിഭാഗം നിലവിലില്ല.

യഥാർത്ഥ ബൈറ്റുകൾ:

00000370 0c 00 00 00 00 00 00 00 01 00 00 00 02 00 00 00 |...........| 00000380 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |............|

സമർപ്പിച്ച ഘടന:

ടൈപ്പ്ഡെഫ് സ്ട്രക്റ്റ് (Elf64_Addr r_offset; Elf64_Xword r_info; Elf64_Sxword r_addend; ) Elf64_Rela;

    370 0: r_offset = 0xC: വിലാസം. ടെക്‌സ്‌റ്റിലെ വിലാസം അതിന്റെ വിലാസം മാറ്റപ്പെടും

    370 8: r_info = 0x200000001. 2 ഫീൽഡുകൾ അടങ്ങിയിരിക്കുന്നു:

    • ELF64_R_TYPE = 0x1: മൂല്യം കൃത്യമായ ആർക്കിടെക്ചറിനെ ആശ്രയിച്ചിരിക്കുന്നു.
    • ELF64_R_SYM = 0x2: വിലാസം ചൂണ്ടിക്കാണിച്ച പാർട്ടീഷന്റെ സൂചിക, അതിനാൽ സൂചിക 2-ൽ ഉള്ള .ഡാറ്റ.

    AMD64 ABI പറയുന്നത്, ടൈപ്പ് 1 നെ R_X86_64_64 എന്ന് വിളിക്കുന്നു എന്നും അത് S+A പ്രവർത്തനത്തെ പ്രതിനിധീകരിക്കുന്നു:

    • എസ്: ഒബ്‌ജക്റ്റ് ഫയലിലെ ചിഹ്നത്തിന്റെ മൂല്യം, ഇവിടെ 0, കാരണം നമ്മൾ മൊവാബ്‌സ് $0x0,%rsi-ൽ നിന്ന് 00 00 00 00 00 00 00 00 ചൂണ്ടിക്കാണിക്കുന്നു
    • a: r_added ഫീൽഡിൽ നിലവിലുള്ള കൂട്ടിച്ചേർക്കൽ

    നീക്കം പ്രവർത്തിക്കുന്ന പാർട്ടീഷനിലേക്ക് ഈ വിലാസം ചേർക്കുന്നു.

    ഈ നീക്കം പ്രവർത്തനം 8 ബൈറ്റുകളെ ബാധിക്കുന്നു.

    380 0: r_addend = 0

അതിനാൽ ഞങ്ങളുടെ ഉദാഹരണത്തിൽ, പുതിയ വിലാസം ഇതായിരിക്കുമെന്ന് ഞങ്ങൾ നിഗമനം ചെയ്യുന്നു: S + A = .data + 0 , അങ്ങനെ ഡാറ്റ വിഭാഗത്തിലെ ആദ്യത്തേത്.

പ്രോഗ്രാം തലക്കെട്ട് പട്ടിക

എക്സിക്യൂട്ടബിൾ ഫയലിൽ മാത്രമേ ദൃശ്യമാകൂ.

പ്രോസസ്സിന്റെ വെർച്വൽ മെമ്മറിയിൽ എക്സിക്യൂട്ടബിൾ ഫയൽ എങ്ങനെ സ്ഥാപിക്കണം എന്നതിനെക്കുറിച്ചുള്ള വിവരങ്ങൾ അടങ്ങിയിരിക്കുന്നു.

ഒരു എക്സിക്യൂട്ടബിൾ ഫയൽ ലിങ്കർ മുഖേന ഒരു ഒബ്ജക്റ്റ് ഫയൽ സൃഷ്ടിക്കുന്നു. ലിങ്കർ ചെയ്യുന്ന പ്രധാന ജോലികൾ:

    ഒബ്ജക്റ്റ് ഫയലുകളുടെ ഏതൊക്കെ വിഭാഗങ്ങൾ എക്സിക്യൂട്ടബിൾ ഫയലിന്റെ ഏതൊക്കെ വിഭാഗങ്ങളിലേക്ക് പോകുമെന്ന് നിർണ്ണയിക്കുക.

    Binutils-ൽ, ഇത് ലിങ്കർ സ്‌ക്രിപ്റ്റ് പാഴ്‌സ് ചെയ്യുന്നതിനും ധാരാളം ഡിഫോൾട്ടുകളിൽ പ്രവർത്തിക്കുന്നതിനും വേണ്ടി വരുന്നു.

    നിങ്ങൾക്ക് ld --verbose-നൊപ്പം ഉപയോഗിക്കുന്ന സ്ക്രിപ്റ്റ് ലിങ്കർ നേടുകയും ld -T ഉപയോഗിച്ച് ഒരു ഇഷ്‌ടാനുസൃത ഒന്ന് ഇൻസ്റ്റാൾ ചെയ്യുകയും ചെയ്യാം.

    ടെക്സ്റ്റ് വിഭാഗങ്ങളിലൂടെ നാവിഗേറ്റ് ചെയ്യുക. ഒന്നിലധികം പാർട്ടീഷനുകൾ മെമ്മറിയിലേക്ക് എങ്ങനെ യോജിക്കുന്നു എന്നതിനെ ആശ്രയിച്ചിരിക്കുന്നു.

readelf -l hello_world.out നൽകുന്നു:

Elf ഫയൽ തരം EXEC ആണ് (എക്‌സിക്യൂട്ടബിൾ ഫയൽ) എൻട്രി പോയിന്റ് 0x4000b0 ഓഫ്‌സെറ്റ് 64 പ്രോഗ്രാം ഹെഡറുകൾ മുതൽ 2 പ്രോഗ്രാം ഹെഡറുകൾ ഉണ്ട്: തരം ഓഫ്‌സെറ്റ് VirtAddr PhysAddr FileSiz MemSiz ഫ്ലാഗുകൾ വിന്യസിക്കുക LOAD 0x00000000000000000000000 0x00000000004 00000 0x0000000000000d7 0x0000000000000000000d7 R E 200000 ലോഡ് 0x00000000000000d8 0x0000000000000006 8 0x0000000000 00000d 0x00000000000000d RW 200000 വിഭാഗം മുതൽ സെഗ്‌മെന്റ് മാപ്പിംഗ്: സെഗ്‌മെന്റ് വിഭാഗങ്ങൾ... 00 .ടെക്‌സ്റ്റ് 01 .ഡാറ്റ

ELF ഹെഡറിൽ, e_phoff , e_phnum, e_phentsize എന്നിവ ഞങ്ങളോട് പറഞ്ഞു, 0x40 ൽ ആരംഭിക്കുന്ന 2 പ്രോഗ്രാം ഹെഡറുകൾ ഓരോന്നിനും 0x38 ബൈറ്റുകൾ നീളമുണ്ട്, അതിനാൽ അവ:

00000040 01 00 00 00 05 00 00 00 00 00 00 00 00 00 00 00 |...........| 00000050 00 00 40 00 00 00 00 00 00 00 40 00 00 00 00 00 |..@.......@.....| 00000060 d7 00 00 00 00 00 00 00 d7 00 00 00 00 00 00 00 |...........| 00000070 00 00 20 00 00 00 00 00 |.. ..... |

00000070 01 00 00 00 06 00 00 00 | .......| 00000080 d8 00 00 00 00 00 00 00 d8 00 60 00 00 00 00 00 |........`.....| 00000090 d8 00 60 00 00 00 00 00 0d 00 00 00 00 00 00 00 |..`............| 000000a0 0d 00 00 00 00 00 00 00 00 00 20 00 00 00 00 00 |.......... .....| ടൈപ്പ്ഡെഫ് struct (Elf64_Word p_type; Elf64_Word p_flags; Elf64_Off p_offset; Elf64_Addr p_vaddr; Elf64_Addr p_paddr; Elf64_Xword p_filesz; Elf64_X; Elf64_X വേഡ്; P_64_X; എച്ച്ഡിആർ;

ആദ്യത്തേതിന്റെ തകർച്ച:

  • 40 0: p_type = 01 00 00 00 = PT_LOAD: TODO. ഇത് മെമ്മറിയിലേക്ക് ലോഡ് ചെയ്യപ്പെടും എന്നാണ് ഇതിനർത്ഥം. മറ്റ് തരങ്ങൾ ഉണ്ടാകണമെന്നില്ല.
  • 40 4: p_flags = 05 00 00 00 = അനുമതികൾ നടപ്പിലാക്കുകയും വായിക്കുകയും ചെയ്യുക, TODO എന്ന് എഴുതരുത്
  • 40 8: p_offset = 8x 00 TODO: ഇത് എന്താണ്? സെഗ്‌മെന്റുകളുടെ തുടക്കം മുതൽ ഇത് ഓഫ്‌സെറ്റുകൾ പോലെ കാണപ്പെടുന്നു. എന്നാൽ ചില ഭാഗങ്ങൾ പരസ്പരം ബന്ധപ്പെട്ടിരിക്കുന്നു എന്ന് ഇത് അർത്ഥമാക്കുമോ? നിങ്ങൾക്ക് ഇത് കുറച്ച് കളിക്കാം: gcc -Wl,-Ttext-segment=0x400030 hello_world.c
  • 50 0: p_vaddr = 00 00 40 00 00 00 00 00: ഈ സെഗ്‌മെന്റ് ലോഡുചെയ്യാൻ വെർച്വൽ മെമ്മറിയുടെ ആരംഭ വിലാസം
  • 50 8: p_paddr = 00 00 40 00 00 00 00 00: മെമ്മറിയിലേക്ക് ലോഡ് ചെയ്യാൻ ഫിസിക്കൽ വിലാസം ആരംഭിക്കുന്നു. പ്രോഗ്രാമിന് ഫിസിക്കൽ വിലാസം സജ്ജീകരിക്കാൻ കഴിയുന്ന സിസ്റ്റങ്ങൾക്കുള്ള ചോദ്യങ്ങൾ മാത്രം. അല്ലെങ്കിൽ, സിസ്റ്റം V സിസ്റ്റങ്ങൾ പോലെ, എന്തും സംഭവിക്കാം. NASM p_vaddrr പകർത്തുമെന്ന് തോന്നുന്നു
  • 60 0: p_filesz = d7 00 00 00 00 00 00 00: TODO vs p_memsz
  • 60 8: p_memsz = d7 00 00 00 00 00 00 00: ചെയ്യേണ്ടത്
  • 70 0: p_align = 00 00 20 00 00 00 00 00: 0 അല്ലെങ്കിൽ 1 എന്നാൽ അലൈൻമെന്റ് ആവശ്യമില്ല TODO, ഇത് എന്താണ് അർത്ഥമാക്കുന്നത്? അല്ലാത്തപക്ഷം മറ്റ് ഫീൽഡുകൾക്കൊപ്പം അനാവശ്യമാണ്

രണ്ടാമത്തേതും സമാനമാണ്.

വിഭാഗം മുതൽ സെഗ്‌മെന്റ് മാപ്പിംഗ്:

വായന വിഭാഗം നമ്മോട് പറയുന്നത്:

  • 0 - segment.text . അതെ, അതിനാൽ ഇത് എക്സിക്യൂട്ടബിൾ ആണ്, എഴുതാൻ പറ്റില്ല.
  • 1 - segment.data.

നിങ്ങളുടെ കമ്പ്യൂട്ടറിൽ ഇൻസ്റ്റാൾ ചെയ്തിട്ടുണ്ടെങ്കിൽ ആന്റിവൈറസ് പ്രോഗ്രാംകഴിയും നിങ്ങളുടെ കമ്പ്യൂട്ടറിലെ എല്ലാ ഫയലുകളും അതുപോലെ ഓരോ ഫയലും വ്യക്തിഗതമായി സ്കാൻ ചെയ്യുക. ഫയലിൽ വലത്-ക്ലിക്കുചെയ്ത് വൈറസുകൾക്കായി ഫയൽ സ്കാൻ ചെയ്യുന്നതിനുള്ള ഉചിതമായ ഓപ്ഷൻ തിരഞ്ഞെടുത്ത് നിങ്ങൾക്ക് ഏത് ഫയലും സ്കാൻ ചെയ്യാൻ കഴിയും.

ഉദാഹരണത്തിന്, ഈ ചിത്രത്തിൽ ഇത് ഹൈലൈറ്റ് ചെയ്തിരിക്കുന്നു my-file.elf ഫയൽ ചെയ്യുക, തുടർന്ന് നിങ്ങൾ ഈ ഫയലിൽ റൈറ്റ് ക്ലിക്ക് ചെയ്ത് ഫയൽ മെനുവിലെ ഓപ്ഷൻ തിരഞ്ഞെടുക്കുക "AVG ഉപയോഗിച്ച് സ്കാൻ ചെയ്യുക". നിങ്ങൾ ഈ ഓപ്ഷൻ തിരഞ്ഞെടുക്കുമ്പോൾ, AVG ആന്റിവൈറസ് തുറന്ന് വൈറസുകൾക്കായി ഫയൽ സ്കാൻ ചെയ്യും.


ചിലപ്പോൾ അതിന്റെ ഫലമായി ഒരു പിശക് സംഭവിക്കാം തെറ്റായ സോഫ്റ്റ്വെയർ ഇൻസ്റ്റാളേഷൻ, ഇത് ഇൻസ്റ്റലേഷൻ പ്രക്രിയയിൽ നേരിട്ട ഒരു പ്രശ്നം മൂലമാകാം. ഇത് നിങ്ങളുടെ ഓപ്പറേറ്റിംഗ് സിസ്റ്റത്തെ തടസ്സപ്പെടുത്തിയേക്കാം നിങ്ങളുടെ ELF ഫയൽ ശരിയായ ആപ്ലിക്കേഷൻ സോഫ്റ്റ്‌വെയറിലേക്ക് ലിങ്ക് ചെയ്യുക, വിളിക്കപ്പെടുന്നവയെ സ്വാധീനിക്കുന്നു "ഫയൽ എക്സ്റ്റൻഷൻ അസോസിയേഷനുകൾ".

ചിലപ്പോൾ ലളിതവും ഡോൾഫിൻ (എമുലേറ്റർ) വീണ്ടും ഇൻസ്റ്റാൾ ചെയ്യുന്നു ELF-നെ ഡോൾഫിനുമായി (എമുലേറ്റർ) ശരിയായി ലിങ്ക് ചെയ്തുകൊണ്ട് നിങ്ങളുടെ പ്രശ്നം പരിഹരിക്കാം. മറ്റ് സന്ദർഭങ്ങളിൽ, ഫയൽ അസോസിയേഷനുകളിലെ പ്രശ്നങ്ങൾ ഉണ്ടാകാം മോശം സോഫ്റ്റ്വെയർ പ്രോഗ്രാമിംഗ്ഡെവലപ്പർ, കൂടുതൽ സഹായത്തിനായി നിങ്ങൾ ഡെവലപ്പറെ ബന്ധപ്പെടേണ്ടതായി വന്നേക്കാം.


ഉപദേശം:നിങ്ങൾക്ക് ഏറ്റവും പുതിയ പാച്ചുകളും അപ്ഡേറ്റുകളും ഉണ്ടെന്ന് ഉറപ്പാക്കാൻ ഏറ്റവും പുതിയ പതിപ്പിലേക്ക് ഡോൾഫിൻ (എമുലേറ്റർ) അപ്ഡേറ്റ് ചെയ്യാൻ ശ്രമിക്കുക.


ഇത് വളരെ വ്യക്തമായി തോന്നിയേക്കാം, പക്ഷേ പലപ്പോഴും ELF ഫയൽ തന്നെ പ്രശ്നം ഉണ്ടാക്കിയേക്കാം. നിങ്ങൾക്ക് ഒരു ഇമെയിൽ അറ്റാച്ച്‌മെന്റ് വഴി ഒരു ഫയൽ ലഭിക്കുകയോ വെബ്‌സൈറ്റിൽ നിന്ന് ഡൗൺലോഡ് ചെയ്യുകയോ ചെയ്‌താൽ ഡൗൺലോഡ് പ്രക്രിയ തടസ്സപ്പെട്ടു (വൈദ്യുതി തടസ്സമോ മറ്റ് കാരണങ്ങളോ പോലെ), ഫയൽ കേടായേക്കാം. സാധ്യമെങ്കിൽ, ELF ഫയലിന്റെ ഒരു പുതിയ പകർപ്പ് എടുത്ത് അത് വീണ്ടും തുറക്കാൻ ശ്രമിക്കുക.


ശ്രദ്ധയോടെ:ഒരു കേടായ ഫയൽ നിങ്ങളുടെ പിസിയിലെ മുമ്പത്തെ അല്ലെങ്കിൽ നിലവിലുള്ള ക്ഷുദ്രവെയറിന് കൊളാറ്ററൽ കേടുപാടുകൾ വരുത്തും, അതിനാൽ നിങ്ങളുടെ കമ്പ്യൂട്ടറിനെ കാലികമായ ആന്റിവൈറസ് ഉപയോഗിച്ച് അപ്-ടു-ഡേറ്റായി സൂക്ഷിക്കേണ്ടത് പ്രധാനമാണ്.


നിങ്ങളുടെ ഫയൽ ELF ആണെങ്കിൽ നിങ്ങളുടെ കമ്പ്യൂട്ടറിലെ ഹാർഡ്‌വെയറുമായി ബന്ധപ്പെട്ടിരിക്കുന്നുനിങ്ങൾക്ക് ആവശ്യമുള്ള ഫയൽ തുറക്കാൻ ഉപകരണ ഡ്രൈവറുകൾ അപ്ഡേറ്റ് ചെയ്യുകഈ ഉപകരണവുമായി ബന്ധപ്പെട്ടിരിക്കുന്നു.

ഈ പ്രശ്നം സാധാരണയായി മീഡിയ ഫയൽ തരങ്ങളുമായി ബന്ധപ്പെട്ടിരിക്കുന്നു, കമ്പ്യൂട്ടറിനുള്ളിൽ ഹാർഡ്‌വെയർ വിജയകരമായി തുറക്കുന്നതിനെ ആശ്രയിച്ചിരിക്കുന്നു, ഉദാ. ശബ്ദ കാർഡ് അല്ലെങ്കിൽ വീഡിയോ കാർഡ്. ഉദാഹരണത്തിന്, നിങ്ങൾ ഒരു ഓഡിയോ ഫയൽ തുറക്കാൻ ശ്രമിക്കുകയാണെങ്കിൽ, അത് തുറക്കാൻ കഴിയുന്നില്ലെങ്കിൽ, നിങ്ങൾക്ക് ഇത് ആവശ്യമായി വന്നേക്കാം സൗണ്ട് കാർഡ് ഡ്രൈവറുകൾ അപ്ഡേറ്റ് ചെയ്യുക.


ഉപദേശം:നിങ്ങൾ ഒരു ELF ഫയൽ തുറക്കാൻ ശ്രമിക്കുമ്പോൾ നിങ്ങൾക്ക് ലഭിക്കും .SYS ഫയൽ പിശക് സന്ദേശം, പ്രശ്നം ഒരുപക്ഷേ ആയിരിക്കാം കേടായതോ കാലഹരണപ്പെട്ടതോ ആയ ഉപകരണ ഡ്രൈവറുകളുമായി ബന്ധപ്പെട്ടിരിക്കുന്നുഅത് അപ്ഡേറ്റ് ചെയ്യേണ്ടതുണ്ട്. DriverDoc പോലുള്ള ഡ്രൈവർ അപ്‌ഡേറ്റ് സോഫ്റ്റ്‌വെയർ ഉപയോഗിച്ച് ഈ പ്രക്രിയ എളുപ്പമാക്കാം.


നടപടികൾ പ്രശ്നം പരിഹരിക്കുന്നില്ലെങ്കിൽ ELF ഫയലുകൾ തുറക്കുന്നതിൽ നിങ്ങൾക്ക് ഇപ്പോഴും പ്രശ്‌നങ്ങളുണ്ട്, ഇത് കാരണമായിരിക്കാം ലഭ്യമായ സിസ്റ്റം വിഭവങ്ങളുടെ അഭാവം. ELF ഫയലുകളുടെ ചില പതിപ്പുകൾ നിങ്ങളുടെ കമ്പ്യൂട്ടറിൽ ശരിയായി തുറക്കുന്നതിന് ഗണ്യമായ അളവിലുള്ള ഉറവിടങ്ങൾ (ഉദാ. മെമ്മറി/റാം, പ്രോസസ്സിംഗ് പവർ) ആവശ്യമായി വന്നേക്കാം. നിങ്ങൾ വളരെ പഴയ കമ്പ്യൂട്ടർ ഹാർഡ്‌വെയറും അതേ സമയം വളരെ പുതിയ ഒരു ഓപ്പറേറ്റിംഗ് സിസ്റ്റവുമാണ് ഉപയോഗിക്കുന്നതെങ്കിൽ ഈ പ്രശ്നം വളരെ സാധാരണമാണ്.

ഓപ്പറേറ്റിംഗ് സിസ്റ്റം (പശ്ചാത്തലത്തിൽ പ്രവർത്തിക്കുന്ന മറ്റ് സേവനങ്ങൾ) കാരണം കമ്പ്യൂട്ടറിന് ഒരു ടാസ്‌ക്ക് നിലനിർത്തുന്നതിൽ പ്രശ്‌നമുണ്ടാകുമ്പോൾ ഈ പ്രശ്‌നം സംഭവിക്കാം. ഒരു ELF ഫയൽ തുറക്കാൻ വളരെയധികം വിഭവങ്ങൾ ഉപയോഗിക്കുന്നു. Nintendo Wii ഗെയിം ഫയൽ തുറക്കുന്നതിന് മുമ്പ് നിങ്ങളുടെ പിസിയിലെ എല്ലാ ആപ്ലിക്കേഷനുകളും ക്ലോസ് ചെയ്യാൻ ശ്രമിക്കുക. നിങ്ങളുടെ കമ്പ്യൂട്ടറിൽ ലഭ്യമായ എല്ലാ ഉറവിടങ്ങളും സ്വതന്ത്രമാക്കുന്നതിലൂടെ, നിങ്ങളുടെ ELF ഫയൽ തുറക്കാൻ ശ്രമിക്കുന്നതിനുള്ള മികച്ച സ്ഥാനത്തായിരിക്കും നിങ്ങൾ.


നിങ്ങൾ എങ്കിൽ മുകളിൽ വിവരിച്ച എല്ലാ ഘട്ടങ്ങളും പൂർത്തിയാക്കിനിങ്ങളുടെ ELF ഫയൽ ഇപ്പോഴും തുറക്കില്ല, നിങ്ങൾ പ്രവർത്തിപ്പിക്കേണ്ടി വന്നേക്കാം ഉപകരണങ്ങൾ അപ്ഡേറ്റ്. മിക്ക കേസുകളിലും, ഹാർഡ്‌വെയറിന്റെ പഴയ പതിപ്പുകൾ ഉപയോഗിക്കുമ്പോൾ പോലും, പ്രോസസ്സിംഗ് പവർ മിക്ക ഉപയോക്തൃ ആപ്ലിക്കേഷനുകൾക്കും മതിയായതിലും കൂടുതലായിരിക്കും (നിങ്ങൾ 3D റെൻഡറിംഗ്, ഫിനാൻഷ്യൽ/സയന്റിഫിക് മോഡലിംഗ് പോലെയുള്ള CPU-ഇന്റൻസീവ് ജോലികൾ ചെയ്യുന്നില്ലെങ്കിൽ തീവ്രമായ മൾട്ടിമീഡിയ വർക്ക്). അങ്ങനെ, നിങ്ങളുടെ കമ്പ്യൂട്ടറിന് മതിയായ മെമ്മറി ഇല്ലായിരിക്കാം(സാധാരണയായി "റാം" അല്ലെങ്കിൽ റാൻഡം ആക്സസ് മെമ്മറി എന്ന് വിളിക്കുന്നു) ഒരു ഫയൽ തുറക്കുന്നതിനുള്ള ചുമതല നിർവഹിക്കുന്നതിന്.

ഡീബഗ്ഗിംഗ് വിവരങ്ങൾ ഉൾപ്പെടുത്താനുള്ള കഴിവുള്ള ഒരു ELF (എക്‌സിക്യൂട്ടബിൾ ആൻഡ് ലിങ്ക് ചെയ്യാവുന്ന ഫോർമാറ്റ്) ഫയലിലേക്ക് സ്റ്റാൻഡേർഡ് ഡെവലപ്‌മെന്റ് ടൂളുകൾ നിങ്ങളുടെ പ്രോഗ്രാം കംപൈൽ ചെയ്യുന്നു. ഫോർമാറ്റ് സ്പെസിഫിക്കേഷൻ വായിക്കാം. കൂടാതെ, ഓരോ ആർക്കിടെക്ചറിനും അതിന്റേതായ സവിശേഷതകളുണ്ട്, അതായത് ARM സവിശേഷതകൾ. ഈ ഫോർമാറ്റ് നമുക്ക് ഹ്രസ്വമായി നോക്കാം.
ELF ഫോർമാറ്റിലുള്ള ഒരു എക്സിക്യൂട്ടബിൾ ഫയൽ ഇനിപ്പറയുന്ന ഭാഗങ്ങൾ ഉൾക്കൊള്ളുന്നു:
1. തലക്കെട്ട് (ELF തലക്കെട്ട്)
ഫയലിനെക്കുറിച്ചും അതിന്റെ പ്രധാന സവിശേഷതകളെക്കുറിച്ചും പൊതുവായ വിവരങ്ങൾ അടങ്ങിയിരിക്കുന്നു.
2. പ്രോഗ്രാം ഹെഡർ ടേബിൾ
ഇത് ഫയൽ വിഭാഗങ്ങളും മെമ്മറി സെഗ്‌മെന്റുകളും തമ്മിലുള്ള കത്തിടപാടുകളുടെ ഒരു പട്ടികയാണ്; ഓരോ സെക്ഷനും ഏത് മെമ്മറി ഏരിയയിലാണ് എഴുതേണ്ടതെന്ന് ഇത് ബൂട്ട്ലോഡറിനോട് പറയുന്നു.
3. വിഭാഗങ്ങൾ
വിഭാഗങ്ങളിൽ ഫയലിലെ എല്ലാ വിവരങ്ങളും അടങ്ങിയിരിക്കുന്നു (പ്രോഗ്രാം, ഡാറ്റ, ഡീബഗ്ഗിംഗ് വിവരങ്ങൾ മുതലായവ)
ഓരോ വിഭാഗത്തിനും ഒരു തരം, പേര്, മറ്റ് പാരാമീറ്ററുകൾ എന്നിവയുണ്ട്. ".ടെക്സ്റ്റ്" വിഭാഗം സാധാരണയായി കോഡ് സംഭരിക്കുന്നു, ".symtab" - പ്രോഗ്രാം ചിഹ്നങ്ങളുടെ ഒരു പട്ടിക (ഫയലുകളുടെയും നടപടിക്രമങ്ങളുടെയും വേരിയബിളുകളുടെയും പേരുകൾ), ".strtab" - സ്ട്രിംഗുകളുടെ ഒരു പട്ടിക, ".debug_" പ്രിഫിക്സുള്ള വിഭാഗങ്ങൾ - ഡീബഗ്ഗിംഗ് വിവരങ്ങൾ മുതലായവ .d. കൂടാതെ, ഫയലിന് സൂചിക 0 ഉള്ള ഒരു ശൂന്യമായ വിഭാഗം ഉണ്ടായിരിക്കണം.
4. വിഭാഗം തലക്കെട്ട് പട്ടിക
സെക്ഷൻ ഹെഡറുകളുടെ ഒരു നിര അടങ്ങുന്ന പട്ടികയാണിത്.
ELF സൃഷ്ടിക്കുന്നു എന്ന വിഭാഗത്തിൽ ഫോർമാറ്റ് കൂടുതൽ വിശദമായി ചർച്ചചെയ്യുന്നു.

DWARF അവലോകനം

DWARF ഒരു സ്റ്റാൻഡേർഡ് ഡീബഗ്ഗിംഗ് വിവര ഫോർമാറ്റാണ്. സ്റ്റാൻഡേർഡ് ഔദ്യോഗിക വെബ്സൈറ്റിൽ നിന്ന് ഡൗൺലോഡ് ചെയ്യാം. ഫോർമാറ്റിന്റെ മികച്ച ഒരു ചെറിയ അവലോകനവും ഉണ്ട്: DWARF ഡീബഗ്ഗിംഗ് ഫോർമാറ്റിലേക്കുള്ള ആമുഖം (മൈക്കൽ ജെ. ഈഗർ).
ഡീബഗ്ഗിംഗ് വിവരങ്ങൾ ആവശ്യമായി വരുന്നത് എന്തുകൊണ്ട്? അത് അനുവദിക്കുന്നു:
  • ബ്രേക്ക്‌പോയിന്റുകൾ ഒരു ഫിസിക്കൽ വിലാസത്തിലല്ല, സോഴ്‌സ് കോഡ് ഫയലിലെ ലൈൻ നമ്പറിലേക്കോ ഫംഗ്‌ഷന്റെ പേരിലേക്കോ സജ്ജമാക്കുക
  • ആഗോള, പ്രാദേശിക വേരിയബിളുകളുടെ മൂല്യങ്ങളും ഫംഗ്‌ഷൻ പാരാമീറ്ററുകളും പ്രദർശിപ്പിക്കുകയും മാറ്റുകയും ചെയ്യുക
  • കോൾ സ്റ്റാക്ക് പ്രദർശിപ്പിക്കുക (ബാക്ക്ട്രെയിസ്)
  • ഒരു അസംബ്ലി നിർദ്ദേശമനുസരിച്ചല്ല, സോഴ്സ് കോഡിന്റെ വരികൾക്കനുസൃതമായി പ്രോഗ്രാം ഘട്ടം ഘട്ടമായി നടപ്പിലാക്കുക
ഈ വിവരങ്ങൾ ഒരു വൃക്ഷ ഘടനയിൽ സംഭരിച്ചിരിക്കുന്നു. ഓരോ ട്രീ നോഡിനും ഒരു രക്ഷകർത്താവ് ഉണ്ട്, കുട്ടികളുണ്ടാകാം, അതിനെ ഒരു DIE (ഡീബഗ്ഗിംഗ് ഇൻഫർമേഷൻ എൻട്രി) എന്ന് വിളിക്കുന്നു. ഓരോ നോഡിനും അതിന്റേതായ ടാഗും (തരം) നോഡിനെ വിവരിക്കുന്ന ആട്രിബ്യൂട്ടുകളുടെ ഒരു ലിസ്റ്റും (പ്രോപ്പർട്ടികൾ) ഉണ്ട്. ആട്രിബ്യൂട്ടുകളിൽ ഡാറ്റ അല്ലെങ്കിൽ മറ്റ് നോഡുകളിലേക്കുള്ള ലിങ്കുകൾ പോലുള്ള എന്തും അടങ്ങിയിരിക്കാം. കൂടാതെ, മരത്തിന് പുറത്ത് സംഭരിച്ചിരിക്കുന്ന വിവരങ്ങളുണ്ട്.
നോഡുകൾ രണ്ട് പ്രധാന തരങ്ങളായി തിരിച്ചിരിക്കുന്നു: ഡാറ്റ വിവരിക്കുന്ന നോഡുകൾ, കോഡ് വിവരിക്കുന്ന നോഡുകൾ.
ഡാറ്റ വിവരിക്കുന്ന നോഡുകൾ:
  1. ഡാറ്റ തരങ്ങൾ:
    • C ലെ int തരം പോലെയുള്ള അടിസ്ഥാന ഡാറ്റ തരങ്ങൾ (DW_TAG_base_type ഉള്ള നോഡ്).
    • സംയോജിത ഡാറ്റ തരങ്ങൾ (പോയിന്ററുകൾ മുതലായവ)
    • അണികൾ
    • ഘടനകൾ, ക്ലാസുകൾ, യൂണിയനുകൾ, ഇന്റർഫേസുകൾ
  2. ഡാറ്റ ഒബ്ജക്റ്റുകൾ:
    • സ്ഥിരാങ്കങ്ങൾ
    • ഫംഗ്ഷൻ പരാമീറ്ററുകൾ
    • വേരിയബിളുകൾ
    • തുടങ്ങിയവ.
ഓരോ ഡാറ്റാ ഒബ്‌ജക്റ്റിനും ഒരു ആട്രിബ്യൂട്ട് DW_AT_location ഉണ്ട്, അത് ഡാറ്റ സ്ഥിതിചെയ്യുന്ന വിലാസം എങ്ങനെ കണക്കാക്കുന്നു എന്ന് വ്യക്തമാക്കുന്നു. ഉദാഹരണത്തിന്, ഒരു വേരിയബിളിന് ഒരു നിശ്ചിത വിലാസം ഉണ്ടായിരിക്കാം, ഒരു രജിസ്റ്ററിലോ സ്റ്റാക്കിലോ ആകാം, അല്ലെങ്കിൽ ഒരു ക്ലാസിലോ ഒബ്‌ജക്റ്റിലോ അംഗമാകാം. ഈ വിലാസം തികച്ചും സങ്കീർണ്ണമായ രീതിയിൽ കണക്കാക്കാം, അതിനാൽ സ്റ്റാൻഡേർഡ് ലൊക്കേഷൻ എക്സ്പ്രഷനുകൾ എന്ന് വിളിക്കുന്നു, അതിൽ ഒരു പ്രത്യേക ഇന്റേണൽ സ്റ്റാക്ക് മെഷീന്റെ ഓപ്പറേറ്റർമാരുടെ ഒരു ശ്രേണി അടങ്ങിയിരിക്കാം.
കോഡ് വിവരിക്കുന്ന നോഡുകൾ:
  1. നടപടിക്രമങ്ങൾ (പ്രവർത്തനങ്ങൾ) - DW_TAG_subprogram എന്ന ടാഗ് ഉള്ള നോഡുകൾ. ഡിസെൻഡന്റ് നോഡുകളിൽ വേരിയബിളുകളുടെ വിവരണങ്ങൾ അടങ്ങിയിരിക്കാം - ഫംഗ്ഷൻ പാരാമീറ്ററുകളും ലോക്കൽ ഫംഗ്ഷൻ വേരിയബിളുകളും.
  2. സമാഹരണ യൂണിറ്റ്. പ്രോഗ്രാം വിവരങ്ങൾ ഉൾക്കൊള്ളുന്നു കൂടാതെ മറ്റെല്ലാ നോഡുകളുടെയും രക്ഷിതാവാണ്.
മുകളിൽ വിവരിച്ച വിവരങ്ങൾ ".debug_info", ".debug_abbrev" എന്നീ വിഭാഗങ്ങളിലാണ്.
മറ്റ് വിവരങ്ങൾ:
  • ലൈൻ നമ്പറുകളെക്കുറിച്ചുള്ള വിവരങ്ങൾ (വിഭാഗം ".debug_line")
  • മാക്രോകളെക്കുറിച്ചുള്ള വിവരങ്ങൾ (വിഭാഗം ".debug_macinfo")
  • കോൾ ഫ്രെയിം വിവരങ്ങൾ (വിഭാഗം ".debug_frame")

ELF ന്റെ സൃഷ്ടി

elfutils പാക്കേജിൽ നിന്ന് libelf ലൈബ്രറി ഉപയോഗിച്ച് ഞങ്ങൾ EFL ഫോർമാറ്റിൽ ഫയലുകൾ സൃഷ്ടിക്കും. ഇൻറർനെറ്റിൽ ലിബെൽഫ് - ലിബ്ഇഎൽഎഫ് ബൈ ഉദാഹരണം (നിർഭാഗ്യവശാൽ, ഫയലുകൾ സൃഷ്ടിക്കുന്നത് വളരെ ചുരുക്കി വിവരിക്കുന്നു) അതുപോലെ ഡോക്യുമെന്റേഷനും ഉപയോഗിക്കുന്നതിനെക്കുറിച്ച് നല്ലൊരു ലേഖനമുണ്ട്.
ഒരു ഫയൽ സൃഷ്ടിക്കുന്നത് നിരവധി ഘട്ടങ്ങൾ ഉൾക്കൊള്ളുന്നു:
  1. ലൈബൽഫ് ആരംഭിക്കുന്നു
  2. ഒരു ഫയൽ തലക്കെട്ട് സൃഷ്ടിക്കുന്നു (ELF തലക്കെട്ട്)
  3. ഒരു പ്രോഗ്രാം ഹെഡർ ടേബിൾ സൃഷ്ടിക്കുന്നു
  4. വിഭാഗങ്ങൾ സൃഷ്ടിക്കുന്നു
  5. ഒരു ഫയൽ എഴുതുക
നമുക്ക് ഘട്ടങ്ങൾ സൂക്ഷ്മമായി പരിശോധിക്കാം
ലൈബൽഫ് ആരംഭിക്കുന്നു
ആദ്യം നിങ്ങൾ elf_version(EV_CURRENT) ഫംഗ്‌ഷനിലേക്ക് വിളിച്ച് ഫലം പരിശോധിക്കേണ്ടതുണ്ട്. ഇത് EV_NONE എന്നതിന് തുല്യമാണെങ്കിൽ, ഒരു പിശക് സംഭവിച്ചതിനാൽ തുടർ പ്രവർത്തനങ്ങൾ നടത്താൻ കഴിയില്ല. അപ്പോൾ നമുക്ക് ആവശ്യമുള്ള ഫയൽ ഡിസ്കിൽ സൃഷ്ടിക്കേണ്ടതുണ്ട്, അതിന്റെ ഡിസ്ക്രിപ്റ്റർ നേടുകയും അത് elf_begin ഫംഗ്ഷനിലേക്ക് കൈമാറുകയും വേണം:
Elf * elf_begin(int fd, Elf_Cmd cmd, Elf *elf)
  • fd - പുതുതായി തുറന്ന ഫയലിന്റെ ഡിസ്ക്രിപ്റ്റർ
  • cmd - മോഡ് (വിവരങ്ങൾ വായിക്കുന്നതിന് ELF_C_READ, എഴുതുന്നതിന് ELF_C_WRITE അല്ലെങ്കിൽ വായിക്കുന്നതിനും/എഴുതുന്നതിനും ELF_C_RDWR), ഇത് തുറന്ന ഫയൽ മോഡുമായി പൊരുത്തപ്പെടണം (ഞങ്ങളുടെ കാര്യത്തിൽ ELF_C_WRITE)
  • elf - ആർക്കൈവ് ഫയലുകൾ (.a) ഉപയോഗിച്ച് പ്രവർത്തിക്കാൻ മാത്രം ആവശ്യമാണ്, ഞങ്ങളുടെ കാര്യത്തിൽ നിങ്ങൾ 0 പാസ്സാക്കേണ്ടതുണ്ട്
ഫംഗ്‌ഷൻ സൃഷ്‌ടിച്ച ഹാൻഡിലിലേക്ക് ഒരു പോയിന്റർ നൽകുന്നു, അത് എല്ലാ ലിബൽഫ് ഫംഗ്‌ഷനുകളിലും ഉപയോഗിക്കും, പിശകിൽ 0 തിരികെ നൽകും.
ഒരു തലക്കെട്ട് സൃഷ്ടിക്കുന്നു
elf32_newehdr ഫംഗ്‌ഷൻ ഉപയോഗിച്ച് ഒരു പുതിയ ഫയൽ ഹെഡർ സൃഷ്‌ടിച്ചു:
Elf32_Ehdr * elf32_newehdr(Elf *elf);
  • elf_begin ഫംഗ്‌ഷൻ വഴി തിരിച്ചുനൽകിയ elf - ഹാൻഡിൽ
പിശകിൽ 0 നൽകുന്നു അല്ലെങ്കിൽ ഘടനയിലേക്കുള്ള ഒരു പോയിന്റർ നൽകുന്നു - ELF ഫയലിന്റെ തലക്കെട്ട്:
#നിർവ്വചിക്കുക EI_NIDENT 16 ടൈപ്പ്ഡെഫ് സ്ട്രക്റ്റ് ( ഒപ്പിടാത്ത ചാർ ഇ_ഐഡന്റ്; എൽഫ്32_ഹാഫ് ഇ_ടൈപ്പ്; എൽഫ്32_ഹാഫ് ഇ_മെഷീൻ; എൽഫ്32_വേഡ് ഇ_പതിപ്പ്; എൽഫ്32_അഡ്‌ഡിആർ ഇ_എൻട്രി; എൽഫ്_32_ഓഫ്; എൽഫ്32_ഓഫ്; _പതാകകൾ; എൽഫ്32_ഹാഫ് ഇ_ഇഹസൈസ്; ) Elf32_Ehdr;

അതിന്റെ ചില ഫീൽഡുകൾ ഒരു സാധാരണ രീതിയിൽ പൂരിപ്പിച്ചിരിക്കുന്നു, ചിലത് ഞങ്ങൾ പൂരിപ്പിക്കേണ്ടതുണ്ട്:

  • e_ident - ഐഡന്റിഫിക്കേഷൻ ബൈറ്റ് അറേ, ഇനിപ്പറയുന്ന സൂചികകൾ ഉണ്ട്:
    • EI_MAG0, EI_MAG1, EI_MAG2, EI_MAG3 - ഈ 4 ബൈറ്റുകളിൽ elf32_newehdr ഫംഗ്‌ഷൻ ഇതിനകം ചെയ്‌തിരിക്കുന്ന 0x7f,"ELF" പ്രതീകങ്ങൾ അടങ്ങിയിരിക്കണം.
    • EI_DATA - ഫയലിലെ ഡാറ്റ എൻകോഡിംഗ് തരം സൂചിപ്പിക്കുന്നു: ELFDATA2LSB അല്ലെങ്കിൽ ELFDATA2MSB. നിങ്ങൾ ഇതുപോലെ ELFDATA2LSB ഇൻസ്റ്റാൾ ചെയ്യേണ്ടതുണ്ട്: e_ident = ELFDATA2LSB
    • EI_VERSION - ഫയൽ ഹെഡർ പതിപ്പ്, ഞങ്ങൾക്കായി ഇതിനകം സജ്ജമാക്കി
    • EI_PAD - തൊടരുത്
  • e_type - ഫയൽ തരം, ET_NONE ആകാം - തരമില്ല, ET_REL - മാറ്റിസ്ഥാപിക്കാവുന്ന ഫയൽ, ET_EXEC - എക്സിക്യൂട്ടബിൾ ഫയൽ, ET_DYN - പങ്കിട്ട ഒബ്‌ജക്റ്റ് ഫയൽ മുതലായവ. ഞങ്ങൾക്ക് ഫയൽ തരം ET_EXEC ആയി സജ്ജീകരിക്കേണ്ടതുണ്ട്
  • e_machine - ഈ ഫയലിന് ആവശ്യമായ ആർക്കിടെക്ചർ, ഉദാഹരണത്തിന് EM_386 - ഇന്റൽ ആർക്കിടെക്ചറിനായി, ARM-ന് നമ്മൾ ഇവിടെ EM_ARM (40) എഴുതേണ്ടതുണ്ട് - ARM ആർക്കിടെക്ചറിനായി ELF കാണുക
  • e_version - ഫയൽ പതിപ്പ്, EV_CURRENT ആയി സജ്ജമാക്കിയിരിക്കണം
  • e_entry - എൻട്രി പോയിന്റ് വിലാസം, ഞങ്ങൾക്ക് ആവശ്യമില്ല
  • e_phoff - പ്രോഗ്രാം ഹെഡർ ഫയലിൽ ഓഫ്‌സെറ്റ്, e_shoff - സെക്ഷൻ ഹെഡറിന്റെ ഓഫ്‌സെറ്റ്, പൂരിപ്പിക്കരുത്
  • e_flags - പ്രോസസർ-നിർദ്ദിഷ്ട ഫ്ലാഗുകൾ, ഞങ്ങളുടെ ആർക്കിടെക്ചറിനായി (കോർട്ടെക്സ്-M3) 0x05000000 (ABI പതിപ്പ് 5) ആയി സജ്ജീകരിക്കണം.
  • e_ehsize, e_phentsize, e_phnum, e_shentsize, e_shnum - തൊടരുത്
  • e_shstrndx - വിഭാഗത്തിന്റെ തലക്കെട്ടുകളുള്ള വരികളുടെ പട്ടിക സ്ഥിതിചെയ്യുന്ന വിഭാഗത്തിന്റെ എണ്ണം അടങ്ങിയിരിക്കുന്നു. ഞങ്ങൾക്ക് ഇതുവരെ വിഭാഗങ്ങളൊന്നും ഇല്ലാത്തതിനാൽ, ഞങ്ങൾ ഈ നമ്പർ പിന്നീട് സജ്ജീകരിക്കും
ഒരു പ്രോഗ്രാം ഹെഡർ സൃഷ്ടിക്കുന്നു
ഇതിനകം സൂചിപ്പിച്ചതുപോലെ, പ്രോഗ്രാം ഹെഡർ ടേബിൾ ഫയൽ വിഭാഗങ്ങളും മെമ്മറി സെഗ്‌മെന്റുകളും തമ്മിലുള്ള കത്തിടപാടുകളുടെ ഒരു പട്ടികയാണ്, ഇത് ഓരോ വിഭാഗവും എവിടെ എഴുതണമെന്ന് ബൂട്ട്ലോഡറോട് പറയുന്നു. elf32_newphdr ഫംഗ്‌ഷൻ ഉപയോഗിച്ചാണ് തലക്കെട്ട് സൃഷ്‌ടിച്ചത്:
Elf32_Phdr * elf32_newphdr(Elf *elf, size_t കൗണ്ട്);
  • elf നമ്മുടെ കൈപ്പിടിയാണ്
  • എണ്ണം - സൃഷ്ടിക്കേണ്ട പട്ടിക ഘടകങ്ങളുടെ എണ്ണം. ഞങ്ങൾക്ക് ഒരു വിഭാഗം മാത്രമുള്ളതിനാൽ (പ്രോഗ്രാം കോഡിനൊപ്പം), എണ്ണം 1 ന് തുല്യമായിരിക്കും.
പിശകിൽ 0 അല്ലെങ്കിൽ പ്രോഗ്രാം ശീർഷകത്തിലേക്കുള്ള ഒരു പോയിന്റർ നൽകുന്നു.
തലക്കെട്ട് പട്ടികയിലെ ഓരോ ഘടകങ്ങളും ഇനിപ്പറയുന്ന ഘടനയാൽ വിവരിച്ചിരിക്കുന്നു:
ടൈപ്പ്ഡെഫ് സ്ട്രക്റ്റ് (Elf32_Word p_type; Elf32_Off p_offset; Elf32_Addr p_vaddr; Elf32_Addr p_paddr; Elf32_Word p_filesz; Elf32_Word p_memsz; Elf32_Walz; Elf32g2; 2_Phdr;
  • p_type - സെഗ്‌മെന്റ് (വിഭാഗം) തരം, ഇവിടെ നമ്മൾ PT_LOAD - ലോഡിംഗ് സെഗ്‌മെന്റ് വ്യക്തമാക്കണം
  • p_offset - മെമ്മറിയിലേക്ക് ലോഡ് ചെയ്യുന്ന വിഭാഗത്തിന്റെ ഡാറ്റ ആരംഭിക്കുന്ന ഫയലിലെ ഓഫ്സെറ്റുകൾ. ഞങ്ങളെ സംബന്ധിച്ചിടത്തോളം, ഇത് .ടെക്‌സ്റ്റ് വിഭാഗമാണ്, ഇത് ഫയൽ ഹെഡറിനും പ്രോഗ്രാം ഹെഡറിനും തൊട്ടുപിന്നാലെ സ്ഥിതിചെയ്യും; ഈ തലക്കെട്ടുകളുടെ ദൈർഘ്യത്തിന്റെ ആകെത്തുകയായി നമുക്ക് ഓഫ്‌സെറ്റ് കണക്കാക്കാം. elf32_fsize ഫംഗ്‌ഷൻ ഉപയോഗിച്ച് ഏത് തരത്തിന്റേയും ദൈർഘ്യം ലഭിക്കും:
    size_t elf32_fsize (Elf_Type തരം, size_t എണ്ണം, ഒപ്പിടാത്ത ഇൻറ്റ് പതിപ്പ്); ടൈപ്പ് ചെയ്യുക - ഇവിടെ സ്ഥിരമായ ELF_T_xxx, ഞങ്ങൾക്ക് ELF_T_EHDR, ELF_T_PHDR എന്നീ വലുപ്പങ്ങൾ ആവശ്യമാണ്; എണ്ണം - ആവശ്യമുള്ള തരത്തിലുള്ള മൂലകങ്ങളുടെ എണ്ണം, പതിപ്പ് - EV_CURRENT ആയി സജ്ജീകരിച്ചിരിക്കണം
  • p_vaddr, p_paddr - വിഭാഗത്തിലെ ഉള്ളടക്കങ്ങൾ ലോഡ് ചെയ്യുന്ന വെർച്വൽ, ഫിസിക്കൽ വിലാസം. ഞങ്ങൾക്ക് വെർച്വൽ വിലാസങ്ങൾ ഇല്ലാത്തതിനാൽ, ഞങ്ങൾ അത് ഫിസിക്കൽ ഒന്നിന് തുല്യമായി സജ്ജീകരിച്ചിരിക്കുന്നു, ലളിതമായ സാഹചര്യത്തിൽ - 0, കാരണം ഇവിടെയാണ് ഞങ്ങളുടെ പ്രോഗ്രാം ലോഡ് ചെയ്യുന്നത്.
  • p_filesz, p_memsz - ഫയലിലും മെമ്മറിയിലും വിഭാഗത്തിന്റെ വലുപ്പം. ഞങ്ങൾക്ക് അവ സമാനമാണ്, പക്ഷേ പ്രോഗ്രാം കോഡിൽ ഇതുവരെ ഒരു വിഭാഗവുമില്ലാത്തതിനാൽ, ഞങ്ങൾ അവ പിന്നീട് ഇൻസ്റ്റാൾ ചെയ്യും
  • p_flags - ലോഡ് ചെയ്ത മെമ്മറി സെഗ്മെന്റിനുള്ള അനുമതികൾ. PF_R - റീഡ്, PF_W - എഴുതുക, PF_X - എക്സിക്യൂട്ട് അല്ലെങ്കിൽ അവയുടെ സംയോജനമാകാം. p_flags PF_R + PF_X ആയി സജ്ജമാക്കുക
  • p_align - സെഗ്‌മെന്റ് വിന്യാസം, ഞങ്ങൾക്ക് 4 ഉണ്ട്
വിഭാഗങ്ങൾ സൃഷ്ടിക്കുന്നു
തലക്കെട്ടുകൾ സൃഷ്ടിച്ച ശേഷം, നിങ്ങൾക്ക് വിഭാഗങ്ങൾ സൃഷ്ടിക്കാൻ ആരംഭിക്കാം. elf_newscn ഫംഗ്‌ഷൻ ഉപയോഗിച്ച് ഒരു ശൂന്യമായ വിഭാഗം സൃഷ്‌ടിച്ചു:
Elf_Scn * elf_newscn(Elf *elf);
  • elf - elf_begin ഫംഗ്‌ഷൻ മുഖേന നേരത്തെ തിരിച്ചയച്ച ഹാൻഡിൽ
ഫംഗ്‌ഷൻ വിഭാഗത്തിലേക്ക് ഒരു പോയിന്റർ അല്ലെങ്കിൽ പിശകിൽ 0 നൽകുന്നു.
ഒരു വിഭാഗം സൃഷ്ടിച്ച ശേഷം, നിങ്ങൾ സെക്ഷൻ ഹെഡർ പൂരിപ്പിച്ച് ഒരു സെക്ഷൻ ഡാറ്റ ഡിസ്ക്രിപ്റ്റർ സൃഷ്ടിക്കേണ്ടതുണ്ട്.
elf32_getshdr ഫംഗ്‌ഷൻ ഉപയോഗിച്ച് നമുക്ക് സെക്ഷൻ ഹെഡറിലേക്ക് ഒരു പോയിന്റർ ലഭിക്കും:
Elf32_Shdr * elf32_getshdr(Elf_Scn *scn);
  • elf_newscn ഫംഗ്‌ഷനിൽ നിന്ന് ഞങ്ങൾക്ക് ലഭിച്ച വിഭാഗത്തിലേക്കുള്ള ഒരു പോയിന്ററാണ് scn.
വിഭാഗത്തിന്റെ തലക്കെട്ട് ഇതുപോലെ കാണപ്പെടുന്നു:
ടൈപ്പ്ഡെഫ് struct (Elf32_Word sh_name; Elf32_Word sh_type; Elf32_Word sh_flags; Elf32_Addr sh_addr; Elf32_Off sh_offset; Elf32_Word sh__size; Elf32_sh_size; Elf32sh_size; Elf32_sh_kor 2_Word sh_addralign; Elf3 2_Word sh_entsize; ) Elf32_Shdr;
  • sh_name - വിഭാഗത്തിന്റെ പേര് - വിഭാഗം തലക്കെട്ടുകളുടെ (section.shstrtab) സ്ട്രിംഗ് ടേബിളിൽ ഓഫ്‌സെറ്റ് ചെയ്യുക - ചുവടെയുള്ള "സ്ട്രിംഗ് പട്ടികകൾ" കാണുക
  • sh_type - വിഭാഗം ഉള്ളടക്ക തരം, പ്രോഗ്രാം കോഡുള്ള ഒരു വിഭാഗത്തിന് നിങ്ങൾ SHT_PROGBITS സജ്ജീകരിക്കേണ്ടതുണ്ട്, ഒരു സ്ട്രിംഗ് ടേബിളുള്ള വിഭാഗങ്ങൾക്ക് - SHT_STRTAB, ഒരു ചിഹ്ന പട്ടികയ്ക്ക് - SHT_SYMTAB
  • sh_flags എന്നത് സംയോജിപ്പിക്കാൻ കഴിയുന്ന സെക്ഷൻ ഫ്ലാഗുകളാണ്, അവയിൽ നമുക്ക് മൂന്ന് മാത്രം മതി:
    • SHF_ALLOC - വിഭാഗം മെമ്മറിയിലേക്ക് ലോഡ് ചെയ്യപ്പെടും എന്നാണ്
    • SHF_EXECINSTR - വിഭാഗത്തിൽ എക്സിക്യൂട്ടബിൾ കോഡ് അടങ്ങിയിരിക്കുന്നു
    • SHF_STRINGS - വിഭാഗത്തിൽ സ്ട്രിംഗുകളുടെ ഒരു പട്ടിക അടങ്ങിയിരിക്കുന്നു
    അതനുസരിച്ച്, പ്രോഗ്രാമിനൊപ്പം .ടെക്‌സ്റ്റ് വിഭാഗത്തിനായി നിങ്ങൾ SHF_ALLOC + SHF_EXECINSTR ഫ്ലാഗുകൾ സജ്ജീകരിക്കേണ്ടതുണ്ട്
  • sh_addr - വിഭാഗം മെമ്മറിയിലേക്ക് ലോഡ് ചെയ്യുന്ന വിലാസം
  • sh_offset - ഫയലിലെ വിഭാഗത്തിന്റെ ഓഫ്സെറ്റ് - അതിൽ തൊടരുത്, ലൈബ്രറി ഞങ്ങൾക്കായി ഇത് ഇൻസ്റ്റാൾ ചെയ്യും
  • sh_size - സെക്ഷൻ സൈസ് - തൊടരുത്
  • sh_link - ലിങ്ക് ചെയ്‌ത വിഭാഗത്തിന്റെ എണ്ണം അടങ്ങിയിരിക്കുന്നു; വിഭാഗത്തെ അതിന്റെ അനുബന്ധ വരി പട്ടികയുമായി ലിങ്ക് ചെയ്യേണ്ടത് ആവശ്യമാണ് (ചുവടെ കാണുക)
  • sh_info - വിഭാഗത്തിന്റെ തരം അനുസരിച്ച് അധിക വിവരങ്ങൾ, 0 ആയി സജ്ജമാക്കുക
  • sh_addralign - വിലാസ വിന്യാസം, തൊടരുത്
  • sh_entsize - ഒരു വിഭാഗത്തിൽ ഒരേ നീളമുള്ള നിരവധി ഘടകങ്ങൾ അടങ്ങിയിരിക്കുന്നുവെങ്കിൽ, അത്തരം ഒരു മൂലകത്തിന്റെ നീളം സൂചിപ്പിക്കുന്നു, തൊടരുത്
തലക്കെട്ട് പൂരിപ്പിച്ച ശേഷം, elf_newdata ഫംഗ്‌ഷൻ ഉപയോഗിച്ച് നിങ്ങൾ ഒരു സെക്ഷൻ ഡാറ്റ ഡിസ്‌ക്രിപ്‌റ്റർ സൃഷ്‌ടിക്കേണ്ടതുണ്ട്:
Elf_Data * elf_newdata(Elf_Scn *scn);
  • പുതിയ വിഭാഗത്തിലേക്ക് പുതുതായി ലഭിച്ച പോയിന്ററാണ് scn.
ഫംഗ്‌ഷൻ പിശകിൽ 0 നൽകുന്നു, അല്ലെങ്കിൽ പൂരിപ്പിക്കേണ്ട Elf_Data ഘടനയിലേക്കുള്ള ഒരു പോയിന്റർ:
typedef struct ( void* d_buf; Elf_Type d_type; size_t d_size; off_t d_off; size_t d_align; unsigned d_version; ) Elf_Data;
  • d_buf - വിഭാഗത്തിലേക്ക് എഴുതേണ്ട ഡാറ്റയിലേക്കുള്ള പോയിന്റർ
  • d_type - ഡാറ്റ തരം, ELF_T_BYTE എല്ലായിടത്തും ഞങ്ങൾക്ക് അനുയോജ്യമാണ്
  • d_size - ഡാറ്റ വലുപ്പം
  • d_off - വിഭാഗത്തിൽ ഓഫ്‌സെറ്റ്, 0 ആയി സജ്ജമാക്കുക
  • d_align - alignment, 1 ആയി സജ്ജീകരിക്കാം - വിന്യാസമില്ല
  • d_version - പതിപ്പ്, EV_CURRENT ആയി സജ്ജീകരിച്ചിരിക്കണം
പ്രത്യേക വിഭാഗങ്ങൾ
ഞങ്ങളുടെ ആവശ്യങ്ങൾക്ക്, ആവശ്യമായ ഏറ്റവും കുറഞ്ഞ വിഭാഗങ്ങൾ ഞങ്ങൾ സൃഷ്ടിക്കേണ്ടതുണ്ട്:
  • .ടെക്സ്റ്റ് - പ്രോഗ്രാം കോഡുള്ള വിഭാഗം
  • .symtab - ഫയൽ ചിഹ്ന പട്ടിക
  • .strtab എന്നത് .symtab വിഭാഗത്തിൽ നിന്നുള്ള ചിഹ്നങ്ങളുടെ പേരുകൾ ഉൾക്കൊള്ളുന്ന ഒരു സ്ട്രിംഗ് ടേബിളാണ്, കാരണം രണ്ടാമത്തേത് പേരുകൾ തന്നെയല്ല, മറിച്ച് അവയുടെ സൂചികകളാണ് സംഭരിക്കുന്നത്.
  • .shstrtab - വിഭാഗ നാമങ്ങൾ അടങ്ങുന്ന സ്ട്രിംഗ് പട്ടിക
മുമ്പത്തെ വിഭാഗത്തിൽ വിവരിച്ചതുപോലെ എല്ലാ വിഭാഗങ്ങളും സൃഷ്ടിച്ചിട്ടുണ്ട്, എന്നാൽ ഓരോ പ്രത്യേക വിഭാഗത്തിനും അതിന്റേതായ സവിശേഷതകളുണ്ട്.
Section.text
ഈ വിഭാഗത്തിൽ എക്സിക്യൂട്ടബിൾ കോഡ് അടങ്ങിയിരിക്കുന്നു, അതിനാൽ നിങ്ങൾ ഈ കോഡ് ലോഡ് ചെയ്യുന്ന വിലാസത്തിലേക്ക് sh_type SHT_PROGBITS ആയും sh_flags SHF_EXECINSTR + SHF_ALLOC ആയും sh_addr ആയും സജ്ജീകരിക്കേണ്ടതുണ്ട്.
Section.symtab
വിഭാഗത്തിൽ പ്രോഗ്രാമിന്റെ എല്ലാ ചിഹ്നങ്ങളുടെയും (ഫംഗ്ഷനുകളുടെയും) വിവരണവും അവ വിവരിച്ച ഫയലുകളും അടങ്ങിയിരിക്കുന്നു. ഇതിൽ ഇനിപ്പറയുന്ന ഘടകങ്ങൾ അടങ്ങിയിരിക്കുന്നു, ഓരോന്നിനും 16 ബൈറ്റുകൾ നീളമുണ്ട്:
typedef struct (Elf32_Word st_name; Elf32_Addr st_value; Elf32_Word st_size; unsigned char st_info; unsigned char st_other; Elf32_Half st_shndx; ) Elf32_Sym;
  • st_name - ചിഹ്ന നാമം (string table.strtab ലെ സൂചിക)
  • st_value - മൂല്യം (ഒരു ഫംഗ്ഷന്റെ എൻട്രി വിലാസം അല്ലെങ്കിൽ ഒരു ഫയലിന് 0). Cortex-M3 ന് Thumb-2 നിർദ്ദേശ സെറ്റ് ഉള്ളതിനാൽ, ഈ വിലാസം ഒറ്റയായിരിക്കണം (യഥാർത്ഥ വിലാസം + 1)
  • st_size - ഫംഗ്‌ഷൻ കോഡ് ദൈർഘ്യം (ഫയലിന് 0)
  • st_info - ചിഹ്ന തരവും അതിന്റെ വ്യാപ്തിയും. ഈ ഫീൽഡിന്റെ മൂല്യം നിർണ്ണയിക്കാൻ ഒരു മാക്രോ ഉണ്ട്
    #നിർവചിക്കുക ELF32_ST_INFO(b,t) (((b)<<4)+((t)&0xf))
    ഇവിടെ b എന്നത് സ്കോപ്പും t എന്നത് പ്രതീക തരവുമാണ്
    സ്കോപ്പ് STB_LOCAL (മറ്റ് ഒബ്‌ജക്റ്റ് ഫയലുകളിൽ നിന്ന് ദൃശ്യമല്ല) അല്ലെങ്കിൽ STB_GLOBAL (ദൃശ്യം) ആകാം. കാര്യങ്ങൾ ലളിതമാക്കാൻ, ഞങ്ങൾ STB_GLOBAL ഉപയോഗിക്കുന്നു.
    ചിഹ്ന തരം - ഫംഗ്‌ഷനുള്ള STT_FUNC, ഫയലിനായി STT_FILE
  • st_other - 0 ആയി സജ്ജമാക്കുക
  • st_shndx - ചിഹ്നം നിർവചിച്ചിരിക്കുന്ന വിഭാഗത്തിന്റെ സൂചിക (section index.text), അല്ലെങ്കിൽ ഫയലിനുള്ള SHN_ABS.
    ഒരു വിഭാഗത്തിന്റെ സൂചിക അതിന്റെ scn ഡിസ്ക്രിപ്റ്ററിനെ അടിസ്ഥാനമാക്കി elf_ndxscn ഉപയോഗിച്ച് നിർണ്ണയിക്കാനാകും:
    size_t elf_ndxscn (Elf_Scn *scn);

ഈ വിഭാഗം സാധാരണ രീതിയിലാണ് സൃഷ്ടിച്ചിരിക്കുന്നത്, sh_type മാത്രം SHT_SYMTAB-ലേക്ക് സജ്ജീകരിക്കേണ്ടതുണ്ട്, കൂടാതെ index.strtab എന്ന വിഭാഗം sh_link ഫീൽഡിൽ എഴുതണം, അതിനാൽ ഈ വിഭാഗങ്ങൾ ലിങ്ക് ചെയ്യപ്പെടും.
Section.strtab
ഈ വിഭാഗത്തിൽ .symtab വിഭാഗത്തിൽ നിന്നുള്ള എല്ലാ ചിഹ്നങ്ങളുടെയും പേരുകൾ അടങ്ങിയിരിക്കുന്നു. ഒരു സാധാരണ വിഭാഗം പോലെ സൃഷ്‌ടിച്ചു, എന്നാൽ sh_type SHT_STRTAB ആയും sh_flags SHF_STRINGS ആയും സജ്ജമാക്കിയിരിക്കണം, അതിനാൽ ഈ വിഭാഗം ഒരു സ്ട്രിംഗ് ടേബിളായി മാറുന്നു.
സോഴ്‌സ് ടെക്‌സ്‌റ്റിലൂടെ ഒരു അറേയിലേക്ക് കടത്തികൊണ്ട് ഒരു വിഭാഗത്തിനായുള്ള ഡാറ്റ ശേഖരിക്കാൻ കഴിയും, അതിലേക്കുള്ള പോയിന്റർ സെക്ഷൻ ഡാറ്റ ഡിസ്‌ക്രിപ്റ്ററിലേക്ക് (d_buf) എഴുതുന്നു.
Section.shstrtab
സ്വന്തം തലക്കെട്ടുൾപ്പെടെ ഫയലിന്റെ എല്ലാ വിഭാഗങ്ങളുടെയും തലക്കെട്ടുകൾ ഉൾക്കൊള്ളുന്ന സ്ട്രിംഗുകളുടെ പട്ടികയാണ് ഒരു വിഭാഗം. .strtab വിഭാഗത്തിന്റെ അതേ രീതിയിലാണ് ഇത് സൃഷ്ടിച്ചിരിക്കുന്നത്. സൃഷ്ടിച്ചതിനുശേഷം, അതിന്റെ സൂചിക ഫയൽ ഹെഡറിന്റെ e_shstrndx ഫീൽഡിൽ എഴുതണം.
സ്ട്രിംഗ് ടേബിളുകൾ
സ്ട്രിംഗ് ടേബിളുകളിൽ ഒരു നൾ ബൈറ്റിൽ അവസാനിക്കുന്ന തുടർച്ചയായ വരികൾ അടങ്ങിയിരിക്കുന്നു, ഈ പട്ടികയിലെ ആദ്യ ബൈറ്റും 0 ആയിരിക്കണം. പട്ടികയിലെ ഒരു വരിയുടെ സൂചിക, പട്ടികയുടെ തുടക്കം മുതൽ ബൈറ്റുകളിൽ ഓഫ്‌സെറ്റ് ആണ്, അതിനാൽ ആദ്യ വരി "പേര്" സൂചിക 1 ഉണ്ട്, അടുത്ത വരി "var" ന് സൂചിക 6 ഉണ്ട്.
സൂചിക 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 \0 n a m e \0 v a r \0
ഒരു ഫയൽ എഴുതുക
അതിനാൽ, തലക്കെട്ടുകളും വിഭാഗങ്ങളും ഇതിനകം രൂപീകരിച്ചിട്ടുണ്ട്, ഇപ്പോൾ അവ ഒരു ഫയലിൽ എഴുതുകയും ലിബൽഫിൽ പ്രവർത്തിക്കുകയും ചെയ്യേണ്ടതുണ്ട്. elf_update ഫംഗ്‌ഷൻ ഉപയോഗിച്ചാണ് റെക്കോർഡിംഗ് നടത്തുന്നത്:
off_t elf_update(Elf *elf, Elf_Cmd cmd);
  • elf - ഹാൻഡിൽ
  • cmd - കമാൻഡ്, എഴുതാൻ ELF_C_WRITE എന്നതിന് തുല്യമായിരിക്കണം.
ഫംഗ്‌ഷൻ പിശകിൽ -1 നൽകുന്നു. elf_errmsg(-1) ഫംഗ്‌ഷൻ വിളിച്ച് പിശക് ടെക്‌സ്‌റ്റ് ലഭിക്കും, അത് പിശകുള്ള ലൈനിലേക്ക് ഒരു പോയിന്റർ തിരികെ നൽകും.
elf_end ഫംഗ്‌ഷൻ ഉപയോഗിച്ച് ഞങ്ങൾ ലൈബ്രറിയിൽ പ്രവർത്തിക്കുന്നത് പൂർത്തിയാക്കുന്നു, അതിലേക്ക് ഞങ്ങളുടെ ഡിസ്ക്രിപ്റ്റർ കൈമാറുന്നു. മുമ്പ് തുറന്ന ഫയൽ അടയ്ക്കുക മാത്രമാണ് അവശേഷിക്കുന്നത്.
എന്നിരുന്നാലും, ഞങ്ങൾ സൃഷ്ടിച്ച ഫയലിൽ ഡീബഗ്ഗിംഗ് വിവരങ്ങളൊന്നും അടങ്ങിയിട്ടില്ല, അത് ഞങ്ങൾ അടുത്ത വിഭാഗത്തിൽ ചേർക്കും.

DWARF ന്റെ സൃഷ്ടി

ഡോക്യുമെന്റേഷനോടുകൂടിയ ഒരു pdf ഫയലിനൊപ്പം വരുന്ന ലൈബ്രറി ഉപയോഗിച്ച് ഞങ്ങൾ ഡീബഗ്ഗിംഗ് വിവരങ്ങൾ സൃഷ്ടിക്കും (libdwarf2p.1.pdf - A Producer Library Interface to DWARF).
ഡീബഗ്ഗിംഗ് വിവരങ്ങൾ സൃഷ്ടിക്കുന്നത് ഇനിപ്പറയുന്ന ഘട്ടങ്ങൾ ഉൾക്കൊള്ളുന്നു:
  1. നോഡുകൾ സൃഷ്ടിക്കുന്നു (DIE - ഡീബഗ്ഗിംഗ് ഇൻഫർമേഷൻ എൻട്രി)
  2. നോഡ് ആട്രിബ്യൂട്ടുകൾ സൃഷ്ടിക്കുന്നു
  3. ഡാറ്റ തരങ്ങൾ സൃഷ്ടിക്കുന്നു
  4. നടപടിക്രമങ്ങൾ (പ്രവർത്തനങ്ങൾ) സൃഷ്ടിക്കുന്നു
നമുക്ക് ഘട്ടങ്ങൾ സൂക്ഷ്മമായി പരിശോധിക്കാം
ലിബ്ഡ്വാർഫ് പ്രൊഡ്യൂസർ ആരംഭിക്കുന്നു
.symtab വിഭാഗത്തിലെ ചിഹ്നങ്ങൾ സൃഷ്ടിക്കുന്ന അതേ സമയം തന്നെ ഞങ്ങൾ ഡീബഗ്ഗിംഗ് വിവരങ്ങൾ കംപൈൽ ചെയ്യുന്ന സമയത്താണ് സൃഷ്ടിക്കുന്നത്, അതിനാൽ libelf ആരംഭിച്ചതിന് ശേഷവും ELF ഹെഡറും പ്രോഗ്രാം ഹെഡറും സൃഷ്‌ടിച്ചതിന് ശേഷവും വിഭാഗങ്ങൾ സൃഷ്‌ടിക്കുന്നതിന് മുമ്പും ലൈബ്രറി ആരംഭിക്കണം.
ഇനിഷ്യലൈസേഷനായി ഞങ്ങൾ dwarf_producer_init_c ഫംഗ്ഷൻ ഉപയോഗിക്കും. ഡോക്യുമെന്റേഷനിൽ വിവരിച്ചിരിക്കുന്ന ചില സൂക്ഷ്മതകളിൽ വ്യത്യാസമുള്ള നിരവധി ഇനീഷ്യലൈസേഷൻ ഫംഗ്ഷനുകൾ ലൈബ്രറിയിലുണ്ട് (dwarf_producer_init, dwarf_producer_init_b). തത്വത്തിൽ, നിങ്ങൾക്ക് അവയിലേതെങ്കിലും ഉപയോഗിക്കാം.

Dwarf_P_Debug dwarf_producer_init_c(Dwarf_Unsigned ഫ്ലാഗുകൾ, Dwarf_Callback_Func_c func, Dwarf_Handler errhand, Dwarf_Ptr പിശക്, അസാധുവായ * user_data, Dwarf_Error *error)

  • ഫ്ലാഗുകൾ - ചില പാരാമീറ്ററുകൾ നിർണ്ണയിക്കുന്ന നിരവധി സ്ഥിരാങ്കങ്ങളുടെ "അല്ലെങ്കിൽ" സംയോജനം, ഉദാഹരണത്തിന്, ഇൻഫർമേഷൻ ബിറ്റ് ഡെപ്ത്, ബൈറ്റ് സീക്വൻസ് (ലിറ്റിൽ-എൻഡിയൻ, ബിഗ്-എൻഡിയൻ), റീലോക്കേഷൻ ഫോർമാറ്റ്, ഇതിൽ ഞങ്ങൾക്ക് തീർച്ചയായും DW_DLC_WRITE, DW_DLC_SYMBOLIC_RELOCATIONS എന്നിവ ആവശ്യമാണ്
  • ഡീബഗ്ഗിംഗ് വിവരങ്ങളുള്ള ELF വിഭാഗങ്ങൾ സൃഷ്ടിക്കുമ്പോൾ വിളിക്കപ്പെടുന്ന ഒരു കോൾബാക്ക് ഫംഗ്ഷനാണ് func. കൂടുതൽ വിവരങ്ങൾക്ക്, "ഡീബഗ്ഗിംഗ് വിവരങ്ങൾ ഉപയോഗിച്ച് വിഭാഗങ്ങൾ സൃഷ്ടിക്കുന്നു" എന്ന വിഭാഗത്തിൽ താഴെ കാണുക
  • പിശകുകൾ സംഭവിക്കുമ്പോൾ വിളിക്കപ്പെടുന്ന ഒരു ഫംഗ്‌ഷനിലേക്കുള്ള ഒരു പോയിന്ററാണ് errhand. നിങ്ങൾക്ക് 0 അയയ്ക്കാം
  • errarg - errhand ഫംഗ്‌ഷനിലേക്ക് കൈമാറുന്ന ഡാറ്റ 0 ആയി സജ്ജീകരിക്കാം
  • user_data - func ഫംഗ്‌ഷനിലേക്ക് കൈമാറുന്ന ഡാറ്റ 0 ആയി സജ്ജീകരിക്കാം
  • പിശക് - പിശക് കോഡ് തിരികെ നൽകി
ഫംഗ്‌ഷൻ Dwarf_P_Debug നൽകുന്നു - തുടർന്നുള്ള എല്ലാ ഫംഗ്‌ഷനുകളിലും ഉപയോഗിക്കുന്ന ഒരു ഡിസ്‌ക്രിപ്‌റ്റർ, അല്ലെങ്കിൽ ഒരു പിശക് സംഭവിച്ചാൽ -1, പിശകിൽ പിശക് കോഡ് അടങ്ങിയിരിക്കും (ഈ കോഡ് പാസ്സുചെയ്‌ത് dwarf_errmsg ഫംഗ്‌ഷൻ ഉപയോഗിച്ച് അതിന്റെ കോഡ് ഉപയോഗിച്ച് നിങ്ങൾക്ക് പിശക് സന്ദേശത്തിന്റെ വാചകം ലഭിക്കും. അതിലേക്ക്)
നോഡുകൾ സൃഷ്ടിക്കുന്നു (DIE - ഡീബഗ്ഗിംഗ് ഇൻഫർമേഷൻ എൻട്രി)
മുകളിൽ വിവരിച്ചതുപോലെ, ഡീബഗ്ഗിംഗ് വിവരങ്ങൾ ഒരു വൃക്ഷ ഘടന ഉണ്ടാക്കുന്നു. ഈ വൃക്ഷത്തിന്റെ ഒരു നോഡ് സൃഷ്ടിക്കുന്നതിന്, നിങ്ങൾക്ക് ഇത് ആവശ്യമാണ്:
  • dwarf_new_die ഫംഗ്‌ഷൻ ഉപയോഗിച്ച് ഇത് സൃഷ്‌ടിക്കുക
  • അതിലേക്ക് ആട്രിബ്യൂട്ടുകൾ ചേർക്കുക (ഓരോ തരത്തിലുള്ള ആട്രിബ്യൂട്ടും അതിന്റേതായ ഫംഗ്ഷൻ ഉപയോഗിച്ച് ചേർക്കുന്നു, അത് ചുവടെ വിവരിക്കും)
dwarf_new_die ഫംഗ്‌ഷൻ ഉപയോഗിച്ചാണ് നോഡ് സൃഷ്‌ടിച്ചത്:
Dwarf_P_Die dwarf_new_die(Dwarf_P_Debug dbg, Dwarf_Tag new_tag, Dwarf_P_Die parent, Dwarf_P_Die child, Dwarf_P_Die left_sibling, Dwarf_P_Die right_sibling, or * Dwarfr_Error)
  • new_tag - നോഡ് ടാഗ് (തരം) - സ്ഥിരമായ DW_TAG_xxxx, ഇത് libdwarf.h ഫയലിൽ കാണാം
  • രക്ഷിതാവ്, കുട്ടി, ഇടത്_സഹോദരൻ, വലത്_സഹോദരൻ - യഥാക്രമം നോഡിന്റെ രക്ഷിതാവ്, കുട്ടി, ഇടത്, വലത് അയൽക്കാർ. ഈ പരാമീറ്ററുകളെല്ലാം വ്യക്തമാക്കേണ്ട ആവശ്യമില്ല; ഒരെണ്ണം വ്യക്തമാക്കി ബാക്കിയുള്ളതിന് പകരം 0 ഇട്ടാൽ മതി. എല്ലാ പരാമീറ്ററുകളും 0 ആണെങ്കിൽ, നോഡ് ഒന്നുകിൽ റൂട്ട് അല്ലെങ്കിൽ ഒറ്റപ്പെട്ടതായിരിക്കും.
  • പിശക് - അത് സംഭവിക്കുമ്പോൾ പിശക് കോഡ് അടങ്ങിയിരിക്കും
ഫംഗ്‌ഷൻ പിശകിൽ DW_DLV_BADADDR അല്ലെങ്കിൽ വിജയത്തിൽ ഒരു Dwarf_P_Die നോഡ് ഹാൻഡിൽ നൽകുന്നു
നോഡ് ആട്രിബ്യൂട്ടുകൾ സൃഷ്ടിക്കുന്നു
നോഡ് ആട്രിബ്യൂട്ടുകൾ സൃഷ്‌ടിക്കുന്നതിന്, dwarf_add_AT_xxxx ഫംഗ്‌ഷനുകളുടെ ഒരു മുഴുവൻ കുടുംബമുണ്ട്. ആവശ്യമായ ആട്രിബ്യൂട്ട് സൃഷ്‌ടിക്കേണ്ടത് ഏത് ഫംഗ്‌ഷനാണെന്ന് നിർണ്ണയിക്കാൻ ചിലപ്പോൾ ബുദ്ധിമുട്ടാണ്, അതിനാൽ ഞാൻ ലൈബ്രറിയുടെ സോഴ്‌സ് കോഡിലേക്ക് പലതവണ കുഴിച്ചെടുത്തു. ചില പ്രവർത്തനങ്ങൾ ഇവിടെ വിവരിക്കും, ചിലത് ഉചിതമായ വിഭാഗങ്ങളിൽ താഴെ. അവരെല്ലാം ഒരു ഓണർഡി പാരാമീറ്റർ സ്വീകരിക്കുന്നു - ആട്രിബ്യൂട്ട് ചേർക്കുന്ന നോഡിലേക്കുള്ള ഒരു ഹാൻഡിൽ, കൂടാതെ പിശക് പാരാമീറ്ററിൽ ഒരു പിശക് കോഡ് തിരികെ നൽകുക.
dwarf_add_AT_name ഫംഗ്‌ഷൻ ഒരു നോഡിലേക്ക് ഒരു "പേര്" ആട്രിബ്യൂട്ട് (DW_AT_name) ചേർക്കുന്നു. മിക്ക നോഡുകൾക്കും ഒരു പേര് ഉണ്ടായിരിക്കണം (ഉദാഹരണത്തിന്, നടപടിക്രമങ്ങൾ, വേരിയബിളുകൾ, സ്ഥിരാങ്കങ്ങൾ), ചിലതിന് പേരില്ലായിരിക്കാം (ഉദാഹരണത്തിന്, കംപൈലേഷൻ യൂണിറ്റ്)
Dwarf_P_Attribute dwarf_add_AT_name(Dwarf_P_Die ownerdie, char *name, Dwarf_Error *error)
  • പേര് - യഥാർത്ഥ ആട്രിബ്യൂട്ട് മൂല്യം (നോഡിന്റെ പേര്)

dwarf_add_AT_signed_const, dwarf_add_AT_unsigned_const എന്നീ ഫംഗ്‌ഷനുകൾ നോഡിലേക്ക് നിർദ്ദിഷ്‌ട ആട്രിബ്യൂട്ടും അതിന്റെ ഒപ്പിട്ട (അൺസൈഡ്) മൂല്യവും ചേർക്കുന്നു. സ്ഥിരമായ മൂല്യങ്ങൾ, വലുപ്പങ്ങൾ, വരി നമ്പറുകൾ മുതലായവ വ്യക്തമാക്കുന്നതിന് ഒപ്പിട്ടതും ഒപ്പിടാത്തതുമായ ആട്രിബ്യൂട്ടുകൾ ഉപയോഗിക്കുന്നു. ഫംഗ്ഷൻ ഫോർമാറ്റ്:
Dwarf_P_Attribute dwarf_add_AT_(un)signed_const(Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Signed value, Dwarf_Error *error)
  • dbg - Dwarf_P_Debug ഡിസ്ക്രിപ്റ്റർ ലൈബ്രറി ഇനീഷ്യലൈസേഷൻ സമയത്ത് ലഭിച്ചു
  • attr - മൂല്യം സജ്ജീകരിച്ചിരിക്കുന്ന ആട്രിബ്യൂട്ട് - libdwarf.h ഫയലിൽ കാണാവുന്ന DW_AT_xxxx സ്ഥിരാങ്കം
  • മൂല്യം - ആട്രിബ്യൂട്ട് മൂല്യം
പിശക് സംഭവിച്ചാൽ DW_DLV_BADADDR തിരികെ നൽകുക, അല്ലെങ്കിൽ വിജയത്തെക്കുറിച്ചുള്ള ആട്രിബ്യൂട്ട് ഹാൻഡിൽ.
ഒരു കംപൈലേഷൻ യൂണിറ്റ് സൃഷ്ടിക്കുന്നു
ഏതൊരു മരത്തിനും ഒരു റൂട്ട് ഉണ്ടായിരിക്കണം - ഞങ്ങളുടെ കാര്യത്തിൽ, ഇത് പ്രോഗ്രാമിനെക്കുറിച്ചുള്ള വിവരങ്ങൾ ഉൾക്കൊള്ളുന്ന ഒരു കംപൈലേഷൻ യൂണിറ്റാണ് (ഉദാഹരണത്തിന്, പ്രധാന ഫയലിന്റെ പേര്, ഉപയോഗിച്ച പ്രോഗ്രാമിംഗ് ഭാഷ, കംപൈലറിന്റെ പേര്, ചിഹ്നങ്ങളുടെ സംവേദനക്ഷമത ( വേരിയബിളുകൾ, ഫംഗ്‌ഷനുകൾ), പ്രോഗ്രാമിന്റെ പ്രധാന പ്രവർത്തനം, ആരംഭ വിലാസം മുതലായവ). തത്വത്തിൽ, ആട്രിബ്യൂട്ടുകളൊന്നും ആവശ്യമില്ല. ഉദാഹരണത്തിന്, പ്രധാന ഫയലിനെക്കുറിച്ചും കമ്പൈലറിനേയും കുറിച്ചുള്ള വിവരങ്ങൾ നമുക്ക് സൃഷ്ടിക്കാം.
പ്രധാന ഫയൽ വിവരങ്ങൾ
പ്രധാന ഫയലിനെക്കുറിച്ചുള്ള വിവരങ്ങൾ സംഭരിക്കുന്നതിന്, പേര് ആട്രിബ്യൂട്ട് (DW_AT_name) ഉപയോഗിക്കുക, "നോഡ് ആട്രിബ്യൂട്ടുകൾ സൃഷ്ടിക്കുന്നു" എന്ന വിഭാഗത്തിൽ കാണിച്ചിരിക്കുന്നതുപോലെ dwarf_add_AT_name ഫംഗ്ഷൻ ഉപയോഗിക്കുക.
കംപൈലർ വിവരങ്ങൾ
ഞങ്ങൾ dwarf_add_AT_producer ഫംഗ്‌ഷൻ ഉപയോഗിക്കുന്നു:
Dwarf_P_Attribute dwarf_add_AT_name(Dwarf_P_Die ownerdie, char *producer_string, Dwarf_Error *error)
  • പ്രൊഡ്യൂസർ_സ്ട്രിംഗ് - വിവര വാചകമുള്ള സ്ട്രിംഗ്
പിശകിൽ DW_DLV_BADADDR നൽകുന്നു, അല്ലെങ്കിൽ വിജയത്തെക്കുറിച്ചുള്ള ആട്രിബ്യൂട്ട് ഹാൻഡിൽ.
ഒരു പൊതു വിവര എൻട്രി സൃഷ്ടിക്കുന്നു
സാധാരണഗതിയിൽ, ഒരു ഫംഗ്‌ഷൻ (സബ്റൂട്ടീൻ) വിളിക്കുമ്പോൾ, അതിന്റെ പാരാമീറ്ററുകളും റിട്ടേൺ വിലാസവും സ്റ്റാക്കിലേക്ക് തള്ളപ്പെടും (ഓരോ കംപൈലറും ഇത് വ്യത്യസ്തമായി ചെയ്യാമെങ്കിലും), ഇതിനെയെല്ലാം കോൾ ഫ്രെയിം എന്ന് വിളിക്കുന്നു. ഒരു ഫംഗ്ഷനിൽ നിന്നുള്ള റിട്ടേൺ വിലാസം ശരിയായി നിർണ്ണയിക്കുന്നതിനും ഒരു ബാക്ക്ട്രെയിസ് നിർമ്മിക്കുന്നതിനും ഡീബഗ്ഗറിന് ഫ്രെയിം ഫോർമാറ്റിനെക്കുറിച്ചുള്ള വിവരങ്ങൾ ആവശ്യമാണ് - നിലവിലെ ഫംഗ്ഷനിലേക്ക് ഞങ്ങളെ നയിച്ച ഫംഗ്ഷൻ കോളുകളുടെ ഒരു ശൃംഖലയും ഈ ഫംഗ്ഷനുകളുടെ പാരാമീറ്ററുകളും. സ്റ്റാക്കിൽ സൂക്ഷിച്ചിരിക്കുന്ന പ്രോസസ്സർ രജിസ്റ്ററുകൾ വ്യക്തമാക്കുന്നതും സാധാരണമാണ്. സ്റ്റാക്കിൽ സ്ഥലം റിസർവ് ചെയ്യുകയും പ്രോസസ്സർ രജിസ്റ്ററുകൾ സംരക്ഷിക്കുകയും ചെയ്യുന്ന കോഡിനെ ഫംഗ്ഷൻ പ്രോലോഗ് എന്നും രജിസ്റ്ററുകൾ പുനഃസ്ഥാപിക്കുന്ന കോഡിനെ എപ്പിലോഗ് എന്നും വിളിക്കുന്നു.
ഈ വിവരങ്ങൾ വളരെ കംപൈലറിനെ ആശ്രയിച്ചിരിക്കുന്നു. ഉദാഹരണത്തിന്, ആമുഖവും ഉപസംഹാരവും ചടങ്ങിന്റെ തുടക്കത്തിലും അവസാനത്തിലും ആയിരിക്കണമെന്നില്ല; ചിലപ്പോൾ ഫ്രെയിം ഉപയോഗിക്കുന്നു, ചിലപ്പോൾ അല്ല; പ്രോസസ്സർ രജിസ്റ്ററുകൾ മറ്റ് രജിസ്റ്ററുകളിലും മറ്റും സൂക്ഷിക്കാം.
അതിനാൽ, പ്രോസസ്സർ രജിസ്റ്ററുകൾ അവയുടെ മൂല്യം എങ്ങനെ മാറ്റുന്നുവെന്നും നടപടിക്രമത്തിൽ പ്രവേശിക്കുമ്പോൾ അവ എവിടെ സംരക്ഷിക്കുമെന്നും ഡീബഗ്ഗർ അറിയേണ്ടതുണ്ട്. ഈ വിവരങ്ങളെ വിളിക്കുന്നു കോൾ ഫ്രെയിം വിവരങ്ങൾ - ഫ്രെയിം ഫോർമാറ്റിനെക്കുറിച്ചുള്ള വിവരങ്ങൾ. പ്രോഗ്രാമിലെ ഓരോ വിലാസത്തിനും (കോഡ് അടങ്ങിയത്), മെമ്മറിയിലെ ഫ്രെയിം വിലാസം (കാനോനിക്കൽ ഫ്രെയിം വിലാസം - സിഎഫ്എ), പ്രോസസ്സർ രജിസ്റ്ററുകളെക്കുറിച്ചുള്ള വിവരങ്ങൾ എന്നിവ സൂചിപ്പിച്ചിരിക്കുന്നു, ഉദാഹരണത്തിന്, നിങ്ങൾക്ക് ഇത് സൂചിപ്പിക്കാൻ കഴിയും:
  • നടപടിക്രമത്തിൽ കേസ് സംരക്ഷിക്കപ്പെട്ടിട്ടില്ല
  • നടപടിക്രമത്തിൽ രജിസ്റ്റർ അതിന്റെ മൂല്യം മാറ്റില്ല
  • രജിസ്റ്റർ CFA+n എന്ന വിലാസത്തിലുള്ള സ്റ്റാക്കിൽ സൂക്ഷിച്ചിരിക്കുന്നു
  • രജിസ്റ്റർ മറ്റൊരു രജിസ്റ്ററിൽ സൂക്ഷിച്ചിരിക്കുന്നു
  • രജിസ്റ്റർ ചില വിലാസങ്ങളിൽ മെമ്മറിയിൽ സംഭരിച്ചിരിക്കുന്നു, അത് വ്യക്തമല്ലാത്ത രീതിയിൽ കണക്കാക്കാം
  • തുടങ്ങിയവ.
കോഡിലെ ഓരോ വിലാസത്തിനും വിവരങ്ങൾ വ്യക്തമാക്കേണ്ടതായതിനാൽ, അത് വളരെ വലുതും .debug_frame വിഭാഗത്തിൽ കംപ്രസ് ചെയ്ത രൂപത്തിൽ സംഭരിച്ചിരിക്കുന്നതുമാണ്. വിലാസത്തിൽ നിന്ന് വിലാസത്തിലേക്ക് ഇത് കുറച്ച് മാറുന്നതിനാൽ, അതിന്റെ മാറ്റങ്ങൾ മാത്രമേ DW_CFA_xxxx നിർദ്ദേശങ്ങളുടെ രൂപത്തിൽ എൻകോഡ് ചെയ്തിട്ടുള്ളൂ. ഓരോ നിർദ്ദേശവും ഒരു മാറ്റത്തെ സൂചിപ്പിക്കുന്നു, ഉദാഹരണത്തിന്:
  • DW_CFA_set_loc - പ്രോഗ്രാമിലെ നിലവിലെ വിലാസത്തിലേക്ക് പോയിന്റ് ചെയ്യുന്നു
  • DW_CFA_advance_loc - ഒരു നിശ്ചിത എണ്ണം ബൈറ്റുകൾ ഉപയോഗിച്ച് പോയിന്ററിനെ മുന്നോട്ട് കൊണ്ടുപോകുന്നു
  • DW_CFA_def_cfa - സ്റ്റാക്ക് ഫ്രെയിമിന്റെ വിലാസം സൂചിപ്പിക്കുന്നു (സംഖ്യാ സ്ഥിരാങ്കം)
  • DW_CFA_def_cfa_register - സ്റ്റാക്ക് ഫ്രെയിമിന്റെ വിലാസം സൂചിപ്പിക്കുന്നു (പ്രോസസർ രജിസ്റ്ററിൽ നിന്ന് എടുത്തത്)
  • DW_CFA_def_cfa_expression - സ്റ്റാക്ക് ഫ്രെയിം വിലാസം എങ്ങനെ കണക്കാക്കാമെന്ന് വ്യക്തമാക്കുന്നു
  • DW_CFA_same_value - രജിസ്റ്റർ മാറ്റിയിട്ടില്ലെന്ന് സൂചിപ്പിക്കുന്നു
  • DW_CFA_register - രജിസ്റ്റർ മറ്റൊരു രജിസ്റ്ററിൽ സൂക്ഷിച്ചിട്ടുണ്ടെന്ന് സൂചിപ്പിക്കുക
  • തുടങ്ങിയവ.
.debug_frame വിഭാഗത്തിലെ ഘടകങ്ങൾ രണ്ട് തരത്തിലാകാവുന്ന എൻട്രികളാണ്: കോമൺ ഇൻഫർമേഷൻ എൻട്രി (CIE), ഫ്രെയിം ഡിസ്ക്രിപ്ഷൻ എൻട്രി (FDE). പല എഫ്ഡിഇ റെക്കോർഡുകൾക്കും പൊതുവായുള്ള വിവരങ്ങൾ സിഐഇയിൽ അടങ്ങിയിരിക്കുന്നു; ഏകദേശം പറഞ്ഞാൽ, ഇത് ഒരു പ്രത്യേക തരം നടപടിക്രമത്തെ വിവരിക്കുന്നു. ഓരോ നിർദ്ദിഷ്ട നടപടിക്രമവും FDE-കൾ വിവരിക്കുന്നു. ഒരു നടപടിക്രമം നൽകുമ്പോൾ, ഡീബഗ്ഗർ ആദ്യം CIE-ൽ നിന്നും പിന്നീട് FDE-യിൽ നിന്നും നിർദ്ദേശങ്ങൾ നടപ്പിലാക്കുന്നു.
എന്റെ കംപൈലർ സിഎഫ്എ എസ്പി രജിസ്റ്ററിൽ (r13) ഉള്ള നടപടിക്രമങ്ങൾ സൃഷ്ടിക്കുന്നു. എല്ലാ നടപടിക്രമങ്ങൾക്കുമായി നമുക്ക് ഒരു CIE സൃഷ്ടിക്കാം. ഇതിന് ഒരു ഫംഗ്‌ഷൻ ഉണ്ട്, dwarf_add_frame_cie:
Dwarf_Unsigned dwarf_add_frame_cie(Dwarf_P_Debug dbg, char *augmenter, Dwarf_Small code_align, Dwarf_Small data_align, Dwarf_Small ret_addr_reg, Dwarf_Ptr initr init_bytesf, Dwarf_Ptr init_bytes_ അല്ലെങ്കിൽ);
  • augmenter ഒരു UTF-8 എൻകോഡ് ചെയ്ത സ്‌ട്രിംഗാണ്, ഇതിന്റെ സാന്നിധ്യം CIE അല്ലെങ്കിൽ FDE-യ്‌ക്കായി കൂടുതൽ പ്ലാറ്റ്‌ഫോം-ആശ്രിത വിവരങ്ങൾ ഉണ്ടെന്ന് സൂചിപ്പിക്കുന്നു. ഒരു ശൂന്യമായ വരി ഇടുക
  • code_align - ബൈറ്റുകളിലെ കോഡ് വിന്യാസം (ഞങ്ങൾക്ക് 2 ഉണ്ട്)
  • data_align - ഫ്രെയിമിലെ ഡാറ്റയുടെ വിന്യാസം (സെറ്റ് -4, അതായത് എല്ലാ പാരാമീറ്ററുകളും സ്റ്റാക്കിൽ 4 ബൈറ്റുകൾ എടുക്കുകയും അത് മെമ്മറിയിൽ വളരുകയും ചെയ്യുന്നു)
  • ret_addr_reg - നടപടിക്രമത്തിൽ നിന്നുള്ള മടക്ക വിലാസം അടങ്ങുന്ന ഒരു രജിസ്റ്റർ (ഞങ്ങൾക്ക് 14 ഉണ്ട്)
  • init_bytes - DW_CFA_xxxx നിർദ്ദേശങ്ങൾ അടങ്ങിയ ഒരു അറേ. നിർഭാഗ്യവശാൽ, ഈ അറേ സൃഷ്ടിക്കാൻ സൗകര്യപ്രദമായ മാർഗമില്ല. നിങ്ങൾക്ക് ഇത് സ്വമേധയാ സൃഷ്ടിക്കാം അല്ലെങ്കിൽ സി കംപൈലർ സൃഷ്ടിച്ച elf ഫയലിൽ നോക്കാം, അതാണ് ഞാൻ ചെയ്തത്. എന്റെ കാര്യത്തിൽ, അതിൽ 3 ബൈറ്റുകൾ അടങ്ങിയിരിക്കുന്നു: 0x0C, 0x0D, 0, ഇത് DW_CFA_def_cfa: r13 ofs 0 (CFA രജിസ്റ്റർ r13-ലാണ്, ഓഫ്‌സെറ്റ് 0 ആണ്)
  • init_bytes_len - init_bytes അറേയുടെ നീളം
ഫംഗ്‌ഷൻ DW_DLV_NOCOUNT പിശക് അല്ലെങ്കിൽ ഓരോ നടപടിക്രമത്തിനും ഒരു FDE സൃഷ്‌ടിക്കുമ്പോൾ ഉപയോഗിക്കേണ്ട ഒരു CIE ഹാൻഡിൽ നൽകുന്നു, അത് "ഒരു FDE നടപടിക്രമം സൃഷ്‌ടിക്കുന്നു" എന്ന വിഭാഗത്തിൽ പിന്നീട് നോക്കും.
ഡാറ്റ തരങ്ങൾ സൃഷ്ടിക്കുന്നു
നിങ്ങൾക്ക് നടപടിക്രമങ്ങളും വേരിയബിളുകളും സൃഷ്ടിക്കുന്നതിന് മുമ്പ്, നിങ്ങൾ ആദ്യം ഡാറ്റ തരങ്ങളുമായി പൊരുത്തപ്പെടുന്ന നോഡുകൾ സൃഷ്ടിക്കേണ്ടതുണ്ട്. നിരവധി ഡാറ്റ തരങ്ങളുണ്ട്, പക്ഷേ അവയെല്ലാം അടിസ്ഥാന തരങ്ങളെ അടിസ്ഥാനമാക്കിയുള്ളതാണ് (ഇന്റ, ഡബിൾ, മുതലായവ പോലുള്ള പ്രാഥമിക തരങ്ങൾ), മറ്റ് തരങ്ങൾ അടിസ്ഥാന തരങ്ങളിൽ നിന്നാണ് നിർമ്മിച്ചിരിക്കുന്നത്.
DW_TAG_base_type എന്ന ടാഗ് ഉള്ള നോഡാണ് അടിസ്ഥാന തരം. ഇതിന് ഇനിപ്പറയുന്ന ആട്രിബ്യൂട്ടുകൾ ഉണ്ടായിരിക്കണം:
  • "പേര്" (DW_AT_name)
  • “എൻകോഡിംഗ്” (DW_AT_encoding) - ഏത് തരത്തിലുള്ള ഡാറ്റയാണ് ഈ അടിസ്ഥാന തരത്തെ വിവരിക്കുന്നത് (ഉദാഹരണത്തിന്, DW_ATE_boolean - ലോജിക്കൽ, DW_ATE_float - floating point, DW_ATE_signed - signed integer, DW_ATE_unsigned - unsigned integer, മുതലായവ)
  • “വലിപ്പം” (DW_AT_byte_size - വലുപ്പം ബൈറ്റുകളിലോ DW_AT_bit_size - വലുപ്പം ബിറ്റുകളിലോ)
ഒരു നോഡിൽ മറ്റ് ഓപ്ഷണൽ ആട്രിബ്യൂട്ടുകളും അടങ്ങിയിരിക്കാം.
ഉദാഹരണത്തിന്, ഒരു 32-ബിറ്റ് സൈൻ ചെയ്ത ഇന്റിജർ ബേസ് ടൈപ്പ് "int" സൃഷ്‌ടിക്കുന്നതിന്, DW_TAG_base_type എന്ന ടാഗ് ഉപയോഗിച്ച് ഞങ്ങൾ ഒരു നോഡ് സൃഷ്‌ടിക്കുകയും അതിന്റെ ആട്രിബ്യൂട്ടുകൾ DW_AT_name - "int", DW_AT_encoding - DW_ATE_signed, DW_AT_byte_size - 4 സജ്ജീകരിക്കുകയും വേണം.
അടിസ്ഥാന തരങ്ങൾ സൃഷ്ടിച്ചുകഴിഞ്ഞാൽ, നിങ്ങൾക്ക് അവയിൽ നിന്ന് ഡെറിവേറ്റീവുകൾ ലഭിക്കും. അത്തരം നോഡുകളിൽ DW_AT_type ആട്രിബ്യൂട്ട് ഉണ്ടായിരിക്കണം - അവയുടെ അടിസ്ഥാന തരത്തിലേക്കുള്ള ഒരു റഫറൻസ്. ഉദാഹരണത്തിന്, int-ലേക്കുള്ള ഒരു പോയിന്റർ - DW_TAG_pointer_type ടാഗ് ഉള്ള ഒരു നോഡിൽ DW_AT_type ആട്രിബ്യൂട്ടിൽ മുമ്പ് സൃഷ്ടിച്ച “int” തരത്തിലേക്കുള്ള ഒരു ലിങ്ക് ഉണ്ടായിരിക്കണം.
മറ്റൊരു നോഡിലേക്കുള്ള റഫറൻസുള്ള ഒരു ആട്രിബ്യൂട്ട് dwarf_add_AT_reference ഫംഗ്‌ഷൻ സൃഷ്‌ടിക്കുന്നു:
Dwarf_P_Attribute dwarf_add_AT_reference(Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_P_Die otherdie, Dwarf_Error *error)
  • attr - ആട്രിബ്യൂട്ട്, ഈ സാഹചര്യത്തിൽ DW_AT_type
  • otherdie - പരാമർശിക്കുന്ന തരത്തിന്റെ നോഡിലേക്കുള്ള ഒരു ഹാൻഡിൽ
നടപടിക്രമങ്ങൾ സൃഷ്ടിക്കുന്നു
നടപടിക്രമങ്ങൾ സൃഷ്ടിക്കുന്നതിന്, എനിക്ക് ഒരു തരം ഡീബഗ്ഗിംഗ് വിവരങ്ങൾ കൂടി വിശദീകരിക്കേണ്ടതുണ്ട് - ലൈൻ നമ്പർ വിവരങ്ങൾ. ഓരോ മെഷീൻ നിർദ്ദേശങ്ങളും ഒരു പ്രത്യേക സോഴ്സ് കോഡിലേക്ക് മാപ്പ് ചെയ്യുന്നതിനും പ്രോഗ്രാമിന്റെ ലൈൻ-ബൈ-ലൈൻ ഡീബഗ്ഗിംഗ് അനുവദിക്കുന്നതിനും ഇത് സഹായിക്കുന്നു. ഈ വിവരങ്ങൾ .debug_line വിഭാഗത്തിൽ സംഭരിച്ചിരിക്കുന്നു. ഞങ്ങൾക്ക് മതിയായ ഇടമുണ്ടെങ്കിൽ, ഇത് ഒരു മാട്രിക്‌സ് ആയി സംഭരിക്കപ്പെടും, ഓരോ നിർദ്ദേശത്തിനും ഇതുപോലുള്ള നിരകളുള്ള ഒരു വരി:
  • ഉറവിട ഫയലിന്റെ പേര്
  • ഈ ഫയലിലെ ലൈൻ നമ്പർ
  • ഫയലിലെ കോളം നമ്പർ
  • നിർദ്ദേശം ഒരു പ്രസ്താവനയുടെ തുടക്കമാണോ അല്ലെങ്കിൽ പ്രസ്താവനകളുടെ ഒരു ബ്ലോക്കാണോ എന്ന്
  • തുടങ്ങിയവ.
അത്തരമൊരു മാട്രിക്സ് വളരെ വലുതായിരിക്കും, അതിനാൽ അത് കംപ്രസ് ചെയ്യണം. ഒന്നാമതായി, തനിപ്പകർപ്പ് വരികൾ ഇല്ലാതാക്കപ്പെടും, രണ്ടാമതായി, വരികൾ തന്നെ സംരക്ഷിക്കപ്പെടുന്നില്ല, മറിച്ച് അവയിലെ മാറ്റങ്ങൾ മാത്രം. ഈ മാറ്റങ്ങൾ ഒരു പരിമിതമായ അവസ്ഥ യന്ത്രത്തിനായുള്ള കമാൻഡുകൾ പോലെ കാണപ്പെടുന്നു, കൂടാതെ വിവരങ്ങൾ തന്നെ ഈ മെഷീൻ "എക്സിക്യൂട്ട്" ചെയ്യുന്ന ഒരു പ്രോഗ്രാമായി ഇതിനകം കണക്കാക്കുന്നു. ഈ പ്രോഗ്രാമിന്റെ കമാൻഡുകൾ ഇതുപോലെ കാണപ്പെടുന്നു, ഉദാഹരണത്തിന്, ഇതുപോലെയാണ്: DW_LNS_advance_pc - പ്രോഗ്രാം കൌണ്ടർ ഒരു നിശ്ചിത വിലാസത്തിലേക്ക് മുന്നോട്ട് കൊണ്ടുപോകുക, DW_LNS_set_file - നടപടിക്രമം നിർവചിച്ചിരിക്കുന്ന ഫയൽ സജ്ജമാക്കുക, DW_LNS_const_add_pc - പ്രോഗ്രാം കൌണ്ടറിനെ നിരവധി ബൈറ്റുകൾ മുന്നോട്ട് കൊണ്ടുപോകുക തുടങ്ങിയവ.
ഇത്രയും താഴ്ന്ന തലത്തിൽ ഈ വിവരങ്ങൾ സൃഷ്ടിക്കുന്നത് ബുദ്ധിമുട്ടാണ്, അതിനാൽ ഈ ടാസ്ക് എളുപ്പമാക്കുന്നതിന് ലിബ്ഡ്വാർഫ് നിരവധി പ്രവർത്തനങ്ങൾ നൽകുന്നു.
ഓരോ നിർദ്ദേശത്തിനും ഫയലിന്റെ പേര് സംഭരിക്കുന്നത് ചെലവേറിയതാണ്, അതിനാൽ പേരിന് പകരം അതിന്റെ സൂചിക ഒരു പ്രത്യേക പട്ടികയിൽ സൂക്ഷിക്കുന്നു. ഒരു ഫയൽ സൂചിക സൃഷ്ടിക്കാൻ, നിങ്ങൾ dwarf_add_file_decl ഫംഗ്‌ഷൻ ഉപയോഗിക്കേണ്ടതുണ്ട്:
Dwarf_Unsigned dwarf_add_file_decl(Dwarf_P_Debug dbg, char *name, Dwarf_Unsigned dir_idx, Dwarf_Unsigned time_mod, Dwarf_Unsigned length, Dwarf_Error *error)
  • പേര് - ഫയലിന്റെ പേര്
  • dir_idx - ഫയൽ സ്ഥിതിചെയ്യുന്ന ഫോൾഡറിന്റെ സൂചിക. dwarf_add_directory_decl ഫംഗ്‌ഷൻ ഉപയോഗിച്ച് സൂചിക ലഭിക്കും. മുഴുവൻ പാതകളും ഉപയോഗിക്കുകയാണെങ്കിൽ, നിങ്ങൾക്ക് ഫോൾഡർ സൂചികയായി 0 സജ്ജീകരിക്കാം കൂടാതെ dwarf_add_directory_decl ഉപയോഗിക്കരുത്
  • time_mod - ഫയൽ പരിഷ്‌ക്കരണ സമയം, വ്യക്തമാക്കിയേക്കില്ല (0)
  • നീളം - ഫയൽ വലുപ്പം, ഓപ്ഷണൽ (0)
ഫംഗ്‌ഷൻ ഫയൽ സൂചിക അല്ലെങ്കിൽ DW_DLV_NOCOUNT പിശകിൽ തിരികെ നൽകും.
ലൈൻ നമ്പറുകളെക്കുറിച്ചുള്ള വിവരങ്ങൾ സൃഷ്‌ടിക്കുന്നതിന്, dwarf_add_line_entry_b, dwarf_lne_set_address, dwarf_lne_end_sequence എന്നീ മൂന്ന് ഫംഗ്‌ഷനുകളുണ്ട്, അവ ഞങ്ങൾ ചുവടെ നോക്കും.
ഒരു നടപടിക്രമത്തിനായി ഡീബഗ്ഗിംഗ് വിവരങ്ങൾ സൃഷ്ടിക്കുന്നത് പല ഘട്ടങ്ങളിലായി നടക്കുന്നു:
  • .symtab വിഭാഗത്തിൽ ഒരു നടപടിക്രമ ചിഹ്നം സൃഷ്ടിക്കുന്നു
  • ആട്രിബ്യൂട്ടുകൾ ഉപയോഗിച്ച് ഒരു നടപടിക്രമ നോഡ് സൃഷ്ടിക്കുന്നു
  • ഒരു FDE നടപടിക്രമം സൃഷ്ടിക്കുന്നു
  • നടപടിക്രമ പാരാമീറ്ററുകൾ സൃഷ്ടിക്കുന്നു
  • ലൈൻ നമ്പർ വിവരങ്ങൾ സൃഷ്ടിക്കുന്നു
ഒരു നടപടിക്രമ ചിഹ്നം സൃഷ്ടിക്കുന്നു
Section.symtab വിഭാഗത്തിൽ മുകളിൽ വിവരിച്ചതുപോലെ നടപടിക്രമ ചിഹ്നം സൃഷ്ടിച്ചിരിക്കുന്നു. അതിൽ, നടപടിക്രമങ്ങളുടെ ചിഹ്നങ്ങൾ ഈ നടപടിക്രമങ്ങളുടെ സോഴ്സ് കോഡ് സ്ഥിതിചെയ്യുന്ന ഫയലുകളുടെ ചിഹ്നങ്ങളുമായി ഇടകലർന്നിരിക്കുന്നു. ആദ്യം ഞങ്ങൾ ഒരു ഫയൽ ചിഹ്നം സൃഷ്ടിക്കുന്നു, തുടർന്ന് ഒരു നടപടിക്രമം. ഇത് ഫയലിനെ നിലവിലുള്ളതാക്കുന്നു, അടുത്ത നടപടിക്രമം നിലവിലെ ഫയലിലാണെങ്കിൽ, ഫയൽ ചിഹ്നം വീണ്ടും സൃഷ്ടിക്കേണ്ടതില്ല.
ആട്രിബ്യൂട്ടുകൾ ഉപയോഗിച്ച് ഒരു നടപടിക്രമ നോഡ് സൃഷ്ടിക്കുന്നു
ആദ്യം, ഞങ്ങൾ dwarf_new_die ഫംഗ്‌ഷൻ ഉപയോഗിച്ച് ഒരു നോഡ് സൃഷ്‌ടിക്കുന്നു ("നോഡുകൾ സൃഷ്‌ടിക്കുന്നു" എന്ന വിഭാഗം കാണുക), ടാഗ് ആയി DW_TAG_subprogram വ്യക്തമാക്കുന്നു, കൂടാതെ കംപൈലേഷൻ യൂണിറ്റ് (ഇതൊരു ആഗോള നടപടിക്രമമാണെങ്കിൽ) അല്ലെങ്കിൽ അനുബന്ധ DIE (ലോക്കൽ ആണെങ്കിൽ) രക്ഷിതാവായി. അടുത്തതായി ഞങ്ങൾ ആട്രിബ്യൂട്ടുകൾ സൃഷ്ടിക്കുന്നു:
  • നടപടിക്രമത്തിന്റെ പേര് (function dwarf_add_AT_name, "നോഡ് ആട്രിബ്യൂട്ടുകൾ സൃഷ്ടിക്കുന്നു" കാണുക)
  • നടപടിക്രമ കോഡ് ആരംഭിക്കുന്ന ഫയലിലെ ലൈൻ നമ്പർ (ആട്രിബ്യൂട്ട് DW_AT_decl_line), ഫംഗ്‌ഷൻ dwarf_add_AT_unsigned_const (“നോഡ് ആട്രിബ്യൂട്ടുകൾ സൃഷ്‌ടിക്കുന്നു” കാണുക)
  • നടപടിക്രമത്തിന്റെ ആരംഭ വിലാസം (ആട്രിബ്യൂട്ട് DW_AT_low_pc), ഫംഗ്‌ഷൻ dwarf_add_AT_targ_address, താഴെ കാണുക
  • നടപടിക്രമത്തിന്റെ അവസാന വിലാസം (ആട്രിബ്യൂട്ട് DW_AT_high_pc), ഫംഗ്‌ഷൻ dwarf_add_AT_targ_address, താഴെ കാണുക
  • നടപടിക്രമം നൽകുന്ന ഫലത്തിന്റെ തരം (DW_AT_type ആട്രിബ്യൂട്ട് മുമ്പ് സൃഷ്ടിച്ച തരത്തിലേക്കുള്ള ഒരു ലിങ്കാണ്, "ഡാറ്റ തരങ്ങൾ സൃഷ്ടിക്കുന്നു" കാണുക). നടപടിക്രമം ഒന്നും തിരികെ നൽകുന്നില്ലെങ്കിൽ, ഈ ആട്രിബ്യൂട്ട് സൃഷ്ടിക്കേണ്ടതില്ല
DW_AT_low_pc, DW_AT_high_pc ആട്രിബ്യൂട്ടുകൾ ഇതിനായി പ്രത്യേകം രൂപകൽപ്പന ചെയ്‌ത dwarf_add_AT_targ_address_b ഫംഗ്‌ഷൻ ഉപയോഗിച്ചായിരിക്കണം:
Dwarf_P_Attribute dwarf_add_AT_targ_address_b(Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Unsigned pc_value, Dwarf_Unsigned sym_index, അല്ലെങ്കിൽ Dwarf_Index,
  • attr - ആട്രിബ്യൂട്ട് (DW_AT_low_pc അല്ലെങ്കിൽ DW_AT_high_pc)
  • pc_value - വിലാസ മൂല്യം
  • sym_index - പട്ടികയിലെ നടപടിക്രമ ചിഹ്നത്തിന്റെ സൂചിക.symtab. ഓപ്ഷണൽ, 0 കടന്നുപോകാം
ഫംഗ്‌ഷൻ പിശകിൽ DW_DLV_BADADDR തിരികെ നൽകും.
ഒരു FDE നടപടിക്രമം സൃഷ്ടിക്കുന്നു
"ഒരു പൊതു വിവര എൻട്രി സൃഷ്ടിക്കൽ" വിഭാഗത്തിൽ മുകളിൽ ചർച്ച ചെയ്തതുപോലെ, ഓരോ നടപടിക്രമത്തിനും നിങ്ങൾ ഒരു ഫ്രെയിം ഡിസ്ക്രിപ്റ്റർ സൃഷ്ടിക്കേണ്ടതുണ്ട്, അത് നിരവധി ഘട്ടങ്ങളിൽ സംഭവിക്കുന്നു:
  • ഒരു പുതിയ FDE സൃഷ്ടിക്കുന്നു (ഒരു പൊതു വിവര എൻട്രി സൃഷ്ടിക്കുന്നത് കാണുക)
  • സൃഷ്ടിച്ച എഫ്ഡിഇയെ പൊതുവായ ലിസ്റ്റിലേക്ക് ചേർക്കുന്നു
  • സൃഷ്ടിച്ച FDE-യിലേക്ക് നിർദ്ദേശങ്ങൾ ചേർക്കുന്നു
dwarf_new_fde ഫംഗ്‌ഷൻ ഉപയോഗിച്ച് നിങ്ങൾക്ക് ഒരു പുതിയ FDE സൃഷ്ടിക്കാൻ കഴിയും:
Dwarf_P_Fde dwarf_new_fde(Dwarf_P_Debug dbg, Dwarf_Error *error)
പിശക് സംഭവിച്ചാൽ ഫംഗ്ഷൻ പുതിയ FDE അല്ലെങ്കിൽ DW_DLV_BADADDR-ലേക്ക് ഒരു ഹാൻഡിൽ തിരികെ നൽകും.
dwarf_add_frame_fde ഉപയോഗിച്ച് നിങ്ങൾക്ക് ലിസ്റ്റിലേക്ക് ഒരു പുതിയ FDE അറ്റാച്ചുചെയ്യാം:
Dwarf_Unsigned dwarf_add_frame_fde(Dwarf_P_Debug dbg, Dwarf_P_Fde fde, Dwarf_P_Die die, Dwarf_Addr virt_addr, Dwarf_Addr virt_addr, Dwarf_Unsigned code_Uns, Dxigned
  • fde - ഇപ്പോൾ ലഭിച്ച ഹാൻഡിൽ
  • മരിക്കുക - DIE നടപടിക്രമങ്ങൾ (ആട്രിബ്യൂട്ടുകൾ ഉപയോഗിച്ച് ഒരു നടപടിക്രമ നോഡ് സൃഷ്ടിക്കുന്നത് കാണുക)
  • cie - CIE ഡിസ്ക്രിപ്റ്റർ (ഒരു പൊതു വിവര എൻട്രി സൃഷ്ടിക്കുന്നത് കാണുക)
  • virt_addr - ഞങ്ങളുടെ നടപടിക്രമത്തിന്റെ ആരംഭ വിലാസം
  • code_len - നടപടിക്രമ ദൈർഘ്യം ബൈറ്റുകളിൽ
ഫംഗ്‌ഷൻ പിശകിൽ DW_DLV_NOCOUNT തിരികെ നൽകും.
ഇതിനെല്ലാം ശേഷം, നിങ്ങൾക്ക് ഞങ്ങളുടെ FDE-യിൽ DW_CFA_xxxx നിർദ്ദേശങ്ങൾ ചേർക്കാവുന്നതാണ്. dwarf_add_fde_inst, dwarf_fde_cfa_offset എന്നീ ഫംഗ്ഷനുകൾ ഉപയോഗിച്ചാണ് ഇത് ചെയ്യുന്നത്. ആദ്യത്തേത് നൽകിയിരിക്കുന്ന നിർദ്ദേശങ്ങൾ പട്ടികയിലേക്ക് ചേർക്കുന്നു:
Dwarf_P_Fde dwarf_add_fde_inst(Dwarf_P_Fde fde, Dwarf_Small op, Dwarf_Unsigned val1, Dwarf_Unsigned val2, Dwarf_Error *error)
  • op - നിർദ്ദേശ കോഡ് (DW_CFA_ххххх)
  • val1, val2 - നിർദ്ദേശ പാരാമീറ്ററുകൾ (ഓരോ നിർദ്ദേശങ്ങൾക്കും വ്യത്യസ്തമാണ്, സ്റ്റാൻഡേർഡ്, വിഭാഗം 6.4.2 കോൾ ഫ്രെയിം നിർദ്ദേശങ്ങൾ കാണുക)
dwarf_fde_cfa_offset ഫംഗ്‌ഷൻ DW_CFA_offset നിർദ്ദേശം ചേർക്കുന്നു:
Dwarf_P_Fde dwarf_fde_cfa_offset(Dwarf_P_Fde fde, Dwarf_Unsigned reg, Dwarf_Signed offset, Dwarf_Error *error)
  • fde - സൃഷ്ടിച്ച FDE-ലേക്ക് കൈകാര്യം ചെയ്യുക
  • reg - ഫ്രെയിമിൽ എഴുതിയ രജിസ്റ്റർ
  • ഓഫ്‌സെറ്റ് - ഫ്രെയിമിൽ അതിന്റെ ഓഫ്‌സെറ്റ് (ബൈറ്റുകളിലല്ല, ഫ്രെയിം ഘടകങ്ങളിൽ, ഒരു പൊതു വിവര എൻട്രി സൃഷ്‌ടിക്കുന്നു, ഡാറ്റ_അലൈൻ കാണുക)
ഉദാഹരണത്തിന്, സ്റ്റാക്ക് ഫ്രെയിമിൽ രജിസ്റ്റർ lr (r14) സംഭരിക്കുന്ന പ്രോലോഗ് ഒരു നടപടിക്രമം കംപൈലർ സൃഷ്ടിക്കുന്നു. 1 ന് തുല്യമായ ആദ്യ പാരാമീറ്റർ ഉപയോഗിച്ച് DW_CFA_advance_loc നിർദ്ദേശം ചേർക്കുക എന്നതാണ് ആദ്യ ഘട്ടം, അതായത് പിസി രജിസ്റ്ററിനെ 2 ബൈറ്റുകൾ വർദ്ധിപ്പിക്കുക (ഒരു പൊതു വിവര എൻട്രി സൃഷ്‌ടിക്കുന്നു, code_align കാണുക), തുടർന്ന് പാരാമീറ്റർ 4 ഉപയോഗിച്ച് DW_CFA_def_cfa_offset ചേർക്കുക (ഡാറ്റ ഓഫ്‌സെറ്റ് സജ്ജമാക്കുക 4 ബൈറ്റുകൾ ഉപയോഗിച്ച് ഫ്രെയിം ചെയ്യുക) കൂടാതെ reg=14 offset=1 എന്ന പാരാമീറ്റർ ഉപയോഗിച്ച് dwarf_fde_cfa_offset ഫംഗ്‌ഷനെ വിളിക്കുക, അതായത് CFA-യിൽ നിന്ന് -4 ബൈറ്റുകളുടെ ഓഫ്‌സെറ്റ് ഉപയോഗിച്ച് ഫ്രെയിമിലേക്ക് r14 രജിസ്റ്റർ എഴുതുക എന്നാണ്.
നടപടിക്രമ പാരാമീറ്ററുകൾ സൃഷ്ടിക്കുന്നു
നടപടിക്രമ പാരാമീറ്ററുകൾ സൃഷ്ടിക്കുന്നത് സാധാരണ വേരിയബിളുകൾ സൃഷ്ടിക്കുന്നതിന് സമാനമാണ്, "വേരിയബിളുകളും കോൺസ്റ്റന്റുകളും സൃഷ്ടിക്കുന്നു" കാണുക
ലൈൻ നമ്പറുകളെക്കുറിച്ചുള്ള വിവരങ്ങൾ സൃഷ്ടിക്കുന്നു
ഈ വിവരം ഇതുപോലെയാണ് സൃഷ്ടിച്ചിരിക്കുന്നത്:
  • നടപടിക്രമത്തിന്റെ തുടക്കത്തിൽ dwarf_lne_set_address എന്ന ഫംഗ്‌ഷൻ ഉപയോഗിച്ച് ഞങ്ങൾ നിർദ്ദേശങ്ങളുടെ ഒരു ബ്ലോക്ക് ആരംഭിക്കുന്നു
  • ഓരോ വരി കോഡിനും (അല്ലെങ്കിൽ മെഷീൻ നിർദ്ദേശങ്ങൾ) സോഴ്സ് കോഡിനെക്കുറിച്ചുള്ള വിവരങ്ങൾ ഞങ്ങൾ സൃഷ്ടിക്കുന്നു (dwarf_add_line_entry)
  • നടപടിക്രമത്തിന്റെ അവസാനം, dwarf_lne_end_sequence എന്ന ഫംഗ്‌ഷൻ ഉപയോഗിച്ച് ഞങ്ങൾ നിർദ്ദേശങ്ങളുടെ ബ്ലോക്ക് പൂർത്തിയാക്കുന്നു.
dwarf_lne_set_address ഫംഗ്‌ഷൻ നിർദ്ദേശങ്ങളുടെ ഒരു ബ്ലോക്ക് ആരംഭിക്കുന്ന വിലാസം സജ്ജമാക്കുന്നു:
Dwarf_Unsigned dwarf_lne_set_address(Dwarf_P_Debug dbg, Dwarf_Addr offs, Dwarf_Unsigned symidx, Dwarf_Error *error)
  • ഓഫ്സ് - നടപടിക്രമ വിലാസം (ആദ്യ മെഷീൻ നിർദ്ദേശത്തിന്റെ വിലാസം)
  • sym_idx - ചിഹ്ന സൂചിക (ഓപ്ഷണൽ, നിങ്ങൾക്ക് 0 വ്യക്തമാക്കാം)

dwarf_add_line_entry_b ഫംഗ്‌ഷൻ .debug_line വിഭാഗത്തിലേക്ക് സോഴ്‌സ് കോഡ് ലൈനുകളെക്കുറിച്ചുള്ള വിവരങ്ങൾ ചേർക്കുന്നു. എല്ലാ മെഷീൻ നിർദ്ദേശങ്ങൾക്കും ഞാൻ ഈ ഫംഗ്‌ഷൻ എന്ന് വിളിക്കുന്നു:
Dwarf_Unsigned dwarf_add_line_entry_b(Dwarf_P_Debug dbg, Dwarf_Unsigned file_index, Dwarf_Addr code_offset, Dwarf_Unsigned lineno, Dwarf_Signed_Add_line_entry_b, Dwarf_stBool ആണ് Dwarf_Signed column_number warf_Bool is_epilogue_ start, Dwarf_Bool is_prologue_end, Dwarf_Unsigned isa, Dwarf_Unsigned discriminator, Dwarf_Error *error)
  • file_index - dwarf_add_file_decl ഫംഗ്‌ഷൻ വഴി നേരത്തെ ലഭിച്ച സോഴ്‌സ് കോഡ് ഫയലിന്റെ സൂചിക (“നടപടികൾ സൃഷ്‌ടിക്കുന്നു” കാണുക)
  • code_offset - നിലവിലെ മെഷീൻ നിർദ്ദേശത്തിന്റെ വിലാസം
  • lineno - സോഴ്സ് കോഡ് ഫയലിലെ ലൈൻ നമ്പർ
  • column_number - സോഴ്സ് കോഡ് ഫയലിലെ കോളം നമ്പർ
  • is_source_stmt_begin - 1, നിലവിലെ നിർദ്ദേശം ലൈനോ ലൈനിലെ കോഡിൽ ആദ്യമാണെങ്കിൽ (ഞാൻ എപ്പോഴും 1 ഉപയോഗിക്കുന്നു)
  • is_basic_block_begin - 1 നിലവിലെ നിർദ്ദേശം സ്റ്റേറ്റ്‌മെന്റ് ബ്ലോക്കിൽ ആദ്യമാണെങ്കിൽ (ഞാൻ എപ്പോഴും 0 ഉപയോഗിക്കുന്നു)
  • is_epilogue_begin - 1 നടപടിക്രമം എപ്പിലോഗിൽ നിലവിലുള്ള നിർദ്ദേശം ആദ്യമാണെങ്കിൽ (ആവശ്യമില്ല, എനിക്ക് എപ്പോഴും 0 ഉണ്ട്)
  • is_prologue_end - 1 നടപടിക്രമത്തിന്റെ ആമുഖത്തിലെ അവസാനത്തെ നിർദ്ദേശമാണ് നിലവിലെ നിർദ്ദേശമെങ്കിൽ (ആവശ്യമാണ്!)
  • isa - ഇൻസ്ട്രക്ഷൻ സെറ്റ് ആർക്കിടെക്ചർ. ARM Cortex M3-നായി DW_ISA_ARM_thumb വ്യക്തമാക്കുന്നത് ഉറപ്പാക്കുക!
  • വിവേചനക്കാരൻ. സോഴ്സ് കോഡിന്റെ ഒരു സ്ഥാനം (ഫയൽ, ലൈൻ, കോളം) വ്യത്യസ്ത മെഷീൻ നിർദ്ദേശങ്ങളുമായി പൊരുത്തപ്പെടാം. ഈ സാഹചര്യത്തിൽ, അത്തരം നിർദ്ദേശങ്ങളുടെ സെറ്റുകൾക്കായി വ്യത്യസ്ത വിവേചനക്കാർ ഇൻസ്റ്റാൾ ചെയ്യണം. അത്തരം കേസുകൾ ഇല്ലെങ്കിൽ, അത് 0 ആയിരിക്കണം
ഫംഗ്‌ഷൻ 0 (വിജയം) അല്ലെങ്കിൽ DW_DLV_NOCOUNT (പിശക്) നൽകുന്നു.
അവസാനമായി, dwarf_lne_end_sequence ഫംഗ്‌ഷൻ നടപടിക്രമം പൂർത്തിയാക്കുന്നു:
Dwarf_Unsigned dwarf_lne_end_sequence(Dwarf_P_Debug dbg, Dwarf_Addr വിലാസം; Dwarf_Error *error)
  • വിലാസം - നിലവിലെ മെഷീൻ നിർദ്ദേശത്തിന്റെ വിലാസം
0 (വിജയം) അല്ലെങ്കിൽ DW_DLV_NOCOUNT (പിശക്) നൽകുന്നു.
ഇത് നടപടിക്രമത്തിന്റെ സൃഷ്ടി പൂർത്തിയാക്കുന്നു.
വേരിയബിളുകളും കോൺസ്റ്റന്റുകളും സൃഷ്ടിക്കുന്നു
പൊതുവേ, വേരിയബിളുകൾ വളരെ ലളിതമാണ്. അവർക്ക് ഒരു പേര്, അവരുടെ ഡാറ്റ സ്ഥിതി ചെയ്യുന്ന ഒരു മെമ്മറി ലൊക്കേഷൻ (അല്ലെങ്കിൽ പ്രോസസർ രജിസ്റ്റർ), ആ ഡാറ്റയുടെ തരം എന്നിവയുണ്ട്. വേരിയബിൾ ഗ്ലോബൽ ആണെങ്കിൽ, അതിന്റെ പാരന്റ് കംപൈലേഷൻ യൂണിറ്റ് ആയിരിക്കണം, ലോക്കൽ ആണെങ്കിൽ, അനുബന്ധ നോഡ് (പ്രോസീസർ പരാമീറ്ററുകൾക്ക് ഇത് പ്രത്യേകിച്ച് സത്യമാണ്, അവരുടെ രക്ഷകർത്താവ് നടപടിക്രമം തന്നെ ആയിരിക്കണം). വേരിയബിൾ ഡിക്ലറേഷൻ ഏത് ഫയൽ, വരി, കോളം എന്നിവയിലാണെന്നും നിങ്ങൾക്ക് വ്യക്തമാക്കാം.
ഏറ്റവും ലളിതമായ സാഹചര്യത്തിൽ, ഒരു വേരിയബിളിന്റെ മൂല്യം ചില നിശ്ചിത വിലാസത്തിലാണ് സ്ഥിതി ചെയ്യുന്നത്, എന്നാൽ സ്റ്റാക്കിലോ രജിസ്റ്ററിലോ ഒരു നടപടിക്രമം നൽകുമ്പോൾ പല വേരിയബിളുകളും ചലനാത്മകമായി സൃഷ്ടിക്കപ്പെടുന്നു, ചിലപ്പോൾ മൂല്യത്തിന്റെ വിലാസം കണക്കാക്കുന്നത് വളരെ നിസ്സാരമായിരിക്കും. ഒരു വേരിയബിളിന്റെ മൂല്യം എവിടെയാണെന്ന് വിവരിക്കുന്നതിനുള്ള ഒരു സംവിധാനം സ്റ്റാൻഡേർഡ് നൽകുന്നു - ലൊക്കേഷൻ എക്സ്പ്രഷനുകൾ. ഒരു ഫോർട്ട് പോലുള്ള സ്റ്റാക്ക് മെഷീനിനുള്ള നിർദ്ദേശങ്ങളുടെ (DW_OP_xxxx സ്ഥിരാങ്കങ്ങൾ) ഒരു അഡ്രസ് എക്സ്പ്രഷൻ ആണ്; വാസ്തവത്തിൽ, ഇത് ശാഖകളും നടപടിക്രമങ്ങളും ഗണിത പ്രവർത്തനങ്ങളും ഉള്ള ഒരു പ്രത്യേക ഭാഷയാണ്. ഞങ്ങൾ ഈ ഭാഷയെ പൂർണ്ണമായി അവലോകനം ചെയ്യില്ല; കുറച്ച് നിർദ്ദേശങ്ങളിൽ മാത്രമേ ഞങ്ങൾക്ക് താൽപ്പര്യമുണ്ടാകൂ:
  • DW_OP_addr - വേരിയബിളിന്റെ വിലാസം സൂചിപ്പിക്കുന്നു
  • DW_OP_fbreg - അടിസ്ഥാന രജിസ്റ്ററിൽ നിന്ന് വേരിയബിളിന്റെ ഓഫ്സെറ്റ് സൂചിപ്പിക്കുന്നു (സാധാരണയായി സ്റ്റാക്ക് പോയിന്റർ)
  • DW_OP_reg0… DW_OP_reg31 - വേരിയബിൾ അനുബന്ധ രജിസ്റ്ററിൽ സംഭരിച്ചിട്ടുണ്ടെന്ന് സൂചിപ്പിക്കുന്നു
ഒരു വിലാസ എക്‌സ്‌പ്രഷൻ സൃഷ്‌ടിക്കുന്നതിന്, നിങ്ങൾ ആദ്യം ഒരു ശൂന്യമായ എക്‌സ്‌പ്രഷൻ (dwarf_new_expr) സൃഷ്‌ടിക്കണം, അതിലേക്ക് നിർദ്ദേശങ്ങൾ ചേർക്കുക (dwarf_add_expr_addr, dwarf_add_expr_gen, മുതലായവ) DW_AT_location ആട്രിബ്യൂട്ടിന്റെ (dwarf_location_expr) മൂല്യമായി നോഡിലേക്ക് ചേർക്കുക.
ഒരു ശൂന്യമായ വിലാസ എക്‌സ്‌പ്രഷൻ സൃഷ്‌ടിക്കുന്നതിനുള്ള പ്രവർത്തനം അതിന്റെ ഹാൻഡിൽ അല്ലെങ്കിൽ പിശകിൽ 0 നൽകുന്നു:
Dwarf_Expr dwarf_new_expr(Dwarf_P_Debug dbg, Dwarf_Error *error)
ഒരു എക്സ്പ്രഷനിലേക്ക് നിർദ്ദേശങ്ങൾ ചേർക്കാൻ, നിങ്ങൾ dwarf_add_expr_gen ഫംഗ്ഷൻ ഉപയോഗിക്കേണ്ടതുണ്ട്:
Dwarf_Unsigned dwarf_add_expr_gen(Dwarf_P_Expr expr, Dwarf_Small opcode, Dwarf_Unsigned val1, Dwarf_Unsigned val2, Dwarf_Error *error)
  • opcode - പ്രവർത്തന കോഡ്, സ്ഥിരമായ DW_OP_хххх
  • val1, val2 - നിർദ്ദേശ പാരാമീറ്ററുകൾ (സ്റ്റാൻഡേർഡ് കാണുക)

ഒരു വേരിയബിളിന്റെ വിലാസം വ്യക്തമായി സജ്ജീകരിക്കുന്നതിന്, മുമ്പത്തേതിന് പകരം dwarf_add_expr_addr ഫംഗ്‌ഷൻ ഉപയോഗിക്കണം:
Dwarf_Unsigned dwarf_add_expr_addr(Dwarf_P_Expr expr, Dwarf_Unsigned വിലാസം, Dwarf_Signed sym_index, Dwarf_Error *error)
  • എക്‌സ്‌ആർ എന്നത് നിർദ്ദേശം ചേർത്തിരിക്കുന്ന വിലാസ എക്‌സ്‌പ്രഷനിലേക്കുള്ള ഒരു ഹാൻഡിലാണ്
  • വിലാസം - വേരിയബിൾ വിലാസം
  • sym_index - പട്ടികയിലെ ചിഹ്നത്തിന്റെ സൂചിക.symtab. ഓപ്ഷണൽ, 0 കടന്നുപോകാം
ഫംഗ്‌ഷൻ പിശകിൽ DW_DLV_NOCOUNT നൽകുന്നു.
അവസാനമായി, നിങ്ങൾക്ക് dwarf_add_AT_location_expr ഫംഗ്‌ഷൻ ഉപയോഗിച്ച് സൃഷ്‌ടിച്ച വിലാസ എക്‌സ്‌പ്രഷൻ നോഡിലേക്ക് ചേർക്കാൻ കഴിയും:
Dwarf_P_Attribute dwarf_add_AT_location_expr(Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_P_Expr loc_expr, Dwarf_Error *error)
  • ഉടമസ്ഥൻ - എക്സ്പ്രഷൻ ചേർത്തിരിക്കുന്ന നോഡ്
  • attr - ആട്രിബ്യൂട്ട് (ഞങ്ങളുടെ കാര്യത്തിൽ DW_AT_location)
  • loc_expr - മുമ്പ് സൃഷ്ടിച്ച ഒരു വിലാസ എക്സ്പ്രഷൻ കൈകാര്യം ചെയ്യുക
ഫംഗ്‌ഷൻ ആട്രിബ്യൂട്ട് ഹാൻഡിൽ അല്ലെങ്കിൽ പിശകിൽ DW_DLV_NOCOUNT നൽകുന്നു.
യഥാക്രമം DW_TAG_variable, DW_TAG_formal_parameter, DW_TAG_const_type എന്നീ ടാഗ് ഉള്ള സാധാരണ നോഡുകളാണ് വേരിയബിളുകളും (അതുപോലെ തന്നെ നടപടിക്രമ പാരാമീറ്ററുകളും) സ്ഥിരാങ്കങ്ങളും. അവർക്ക് ഇനിപ്പറയുന്ന ആട്രിബ്യൂട്ടുകൾ ആവശ്യമാണ്:
  • വേരിയബിൾ/സ്ഥിരമായ പേര് (function dwarf_add_AT_name, "നോഡ് ആട്രിബ്യൂട്ടുകൾ സൃഷ്ടിക്കുന്നു" കാണുക)
  • വേരിയബിൾ പ്രഖ്യാപിച്ച ഫയലിലെ ലൈൻ നമ്പർ (DW_AT_decl_line ആട്രിബ്യൂട്ട്), dwarf_add_AT_unsigned_const ഫംഗ്‌ഷൻ (“നോഡ് ആട്രിബ്യൂട്ടുകൾ സൃഷ്‌ടിക്കുന്നു” കാണുക)
  • ഫയൽ നാമ സൂചിക (DW_AT_decl_file ആട്രിബ്യൂട്ട്), dwarf_add_AT_unsigned_const ഫംഗ്‌ഷൻ (“നോഡ് ആട്രിബ്യൂട്ടുകൾ സൃഷ്‌ടിക്കുന്നു” കാണുക)
  • വേരിയബിൾ/സ്ഥിരമായ ഡാറ്റാ തരം (DW_AT_type ആട്രിബ്യൂട്ട് മുമ്പ് സൃഷ്ടിച്ച തരത്തിലേക്കുള്ള ഒരു ലിങ്കാണ്, "ഡാറ്റ തരങ്ങൾ സൃഷ്ടിക്കുന്നു" കാണുക)
  • വിലാസ എക്സ്പ്രഷൻ (മുകളിൽ കാണുക) - ഒരു വേരിയബിളിന് അല്ലെങ്കിൽ നടപടിക്രമ പാരാമീറ്ററിന് ആവശ്യമാണ്
  • അല്ലെങ്കിൽ മൂല്യം - ഒരു സ്ഥിരാങ്കത്തിന് (ആട്രിബ്യൂട്ട് DW_AT_const_value, "നോഡ് ആട്രിബ്യൂട്ടുകൾ സൃഷ്ടിക്കുന്നു" കാണുക)
ഡീബഗ്ഗിംഗ് വിവരങ്ങളുള്ള വിഭാഗങ്ങൾ സൃഷ്ടിക്കുന്നു
ഡീബഗ്ഗിംഗ് ഇൻഫർമേഷൻ ട്രീയുടെ എല്ലാ നോഡുകളും സൃഷ്ടിച്ച ശേഷം, നിങ്ങൾക്ക് അത് ഉപയോഗിച്ച് elf വിഭാഗങ്ങൾ സൃഷ്ടിക്കാൻ തുടങ്ങാം. ഇത് രണ്ട് ഘട്ടങ്ങളിലായാണ് സംഭവിക്കുന്നത്:
  • ആദ്യം നമ്മൾ dwarf_transform_to_disk_form ഫംഗ്‌ഷനെ വിളിക്കേണ്ടതുണ്ട്, അത് ഓരോ വിഭാഗത്തിനും ആവശ്യമായ elf വിഭാഗങ്ങൾ സൃഷ്‌ടിക്കാൻ ഞങ്ങൾ എഴുതിയ ഫംഗ്‌ഷനെ വിളിക്കും.
  • ഓരോ വിഭാഗത്തിനും, dwarf_get_section_bytes ഫംഗ്‌ഷൻ ബന്ധപ്പെട്ട വിഭാഗത്തിലേക്ക് എഴുതേണ്ട ഡാറ്റ ഞങ്ങൾക്ക് തിരികെ നൽകും
ഫംഗ്ഷൻ
dwarf_transform_to_disk_form (Dwarf_P_Debug dbg, Dwarf_Error* പിശക്)
ഞങ്ങൾ സൃഷ്ടിച്ച ഡീബഗ്ഗിംഗ് വിവരങ്ങൾ ബൈനറി ഫോർമാറ്റിലേക്ക് പരിവർത്തനം ചെയ്യുന്നു, പക്ഷേ ഡിസ്കിലേക്ക് ഒന്നും എഴുതുന്നില്ല. ഇത് സൃഷ്ടിച്ച elf വിഭാഗങ്ങളുടെ എണ്ണം അല്ലെങ്കിൽ പിശക് സംഭവിച്ചാൽ DW_DLV_NOCOUNT തിരികെ നൽകും. ഈ സാഹചര്യത്തിൽ, ഓരോ വിഭാഗത്തിനും കോൾബാക്ക് ഫംഗ്‌ഷൻ വിളിക്കപ്പെടും, ലൈബ്രറി ആരംഭിക്കുമ്പോൾ ഞങ്ങൾ അത് dwarf_producer_init_c ഫംഗ്‌ഷനിലേക്ക് കൈമാറി. ഈ ഫംഗ്ഷൻ നമ്മൾ തന്നെ എഴുതണം. അതിന്റെ സ്പെസിഫിക്കേഷൻ ഇപ്രകാരമാണ്:
typedef int (*Dwarf_Callback_Func_c)(char* name, int size, Dwarf_Unsigned തരം, Dwarf_Unsigned ഫ്ലാഗുകൾ, Dwarf_Unsigned ലിങ്ക്, Dwarf_Unsigned info, Dwarf_Unsigned* sect_name_index, അസാധുവായ *t user_d int)
  • പേര് - സൃഷ്ടിക്കേണ്ട elf വിഭാഗത്തിന്റെ പേര്
  • വലിപ്പം - വിഭാഗം വലിപ്പം
  • തരം - വിഭാഗം തരം
  • പതാകകൾ - വിഭാഗം പതാകകൾ
  • ലിങ്ക് - വിഭാഗം ലിങ്ക് ഫീൽഡ്
  • info - വിഭാഗം വിവര ഫീൽഡ്
  • sect_name_index - നിങ്ങൾ വിഭാഗത്തിന്റെ സൂചിക സ്ഥലം മാറ്റങ്ങളോടെ തിരികെ നൽകേണ്ടതുണ്ട് (ഓപ്ഷണൽ)
  • user_data - നമ്മൾ ലൈബ്രറി ഇനീഷ്യലൈസേഷൻ ഫംഗ്‌ഷനിൽ സജ്ജീകരിക്കുന്നത് പോലെ തന്നെ നമുക്ക് കൈമാറും
  • പിശക് - ഇവിടെ നിങ്ങൾക്ക് പിശക് കോഡ് അയയ്ക്കാം
ഈ പ്രവർത്തനത്തിൽ നമ്മൾ ചെയ്യേണ്ടത്:
  • ഒരു പുതിയ വിഭാഗം സൃഷ്‌ടിക്കുക (elf_newscn ഫംഗ്‌ഷൻ, വിഭാഗങ്ങൾ സൃഷ്‌ടിക്കുന്നത് കാണുക)
  • ഒരു സെക്ഷൻ ഹെഡർ സൃഷ്ടിക്കുക (ഫംഗ്ഷൻ elf32_getshdr, ibid.)
  • അത് ശരിയായി പൂരിപ്പിക്കുക (ഐബിഡ് കാണുക.). സെക്ഷൻ ഹെഡർ ഫീൽഡുകൾ ഞങ്ങളുടെ ഫംഗ്‌ഷന്റെ പാരാമീറ്ററുകളുമായി പൊരുത്തപ്പെടുന്നതിനാൽ ഇത് എളുപ്പമാണ്. വിട്ടുപോയ ഫീൽഡുകൾ sh_addr, sh_offset, sh_entsize 0 ആയും sh_addralign 1 ആയും സജ്ജമാക്കുക
  • സൃഷ്‌ടിച്ച വിഭാഗത്തിന്റെ സൂചിക തിരികെ നൽകുക (function elf_ndxscn, “Section.symtab” കാണുക) അല്ലെങ്കിൽ പിശകിൽ -1 (പിശക് കോഡ് പിശകായി സജ്ജീകരിക്കുന്നതിലൂടെ)
  • ഫംഗ്‌ഷനിൽ നിന്ന് മടങ്ങുമ്പോൾ 0 തിരികെ നൽകുന്ന ".rel" വിഭാഗം (ഞങ്ങളുടെ കാര്യത്തിൽ) ഒഴിവാക്കണം
പൂർത്തിയായിക്കഴിഞ്ഞാൽ, dwarf_transform_to_disk_form ഫംഗ്‌ഷൻ സൃഷ്‌ടിച്ച വിഭാഗങ്ങളുടെ എണ്ണം നൽകും. ഈ ഘട്ടങ്ങൾ പിന്തുടർന്ന്, 0 മുതൽ ഒരു ലൂപ്പിൽ ഓരോ വിഭാഗത്തിലൂടെയും ഞങ്ങൾ പോകേണ്ടതുണ്ട്:
  • dwarf_get_section_bytes ഫംഗ്‌ഷൻ ഉപയോഗിച്ച് ഒരു വിഭാഗത്തിലേക്ക് എഴുതാൻ ഡാറ്റ സൃഷ്‌ടിക്കുക:
    Dwarf_Ptr dwarf_get_section_bytes(Dwarf_P_Debug dbg, Dwarf_Signed dwarf_section, Dwarf_Signed *elf_section_index, Dwarf_Unsigned *length, Dwarf_Error* error)
    • dwarf_section - സെക്ഷൻ നമ്പർ. 0..n എന്ന ശ്രേണിയിലായിരിക്കണം, ഇവിടെ n എന്നത് dwarf_transform_to_disk_form ഫംഗ്‌ഷൻ വഴി നമുക്ക് നൽകുന്ന സംഖ്യയാണ്.
    • elf_section_index - ഡാറ്റ എഴുതേണ്ട വിഭാഗത്തിന്റെ സൂചിക നൽകുന്നു
    • ദൈർഘ്യം - ഈ ഡാറ്റയുടെ ദൈർഘ്യം
    • പിശക് - ഉപയോഗിച്ചിട്ടില്ല
    ഫംഗ്ഷൻ സ്വീകരിച്ച ഡാറ്റയിലേക്ക് ഒരു പോയിന്റർ നൽകുന്നു അല്ലെങ്കിൽ 0 (കേസിൽ
    സൃഷ്‌ടിക്കാൻ കൂടുതൽ വിഭാഗങ്ങളൊന്നും ശേഷിക്കാത്തപ്പോൾ)
  • നിലവിലെ വിഭാഗത്തിനായി ഒരു ഡാറ്റ ഡിസ്ക്രിപ്റ്റർ സൃഷ്‌ടിക്കുക (function elf_newdata, സെക്ഷനുകൾ സൃഷ്‌ടിക്കുന്നത് കാണുക) സജ്ജീകരിച്ച് അത് പൂരിപ്പിക്കുക (അവിടെ കാണുക):
    • d_buf - മുമ്പത്തെ ഫംഗ്ഷനിൽ നിന്ന് ഞങ്ങൾക്ക് ലഭിച്ച ഡാറ്റയിലേക്കുള്ള ഒരു പോയിന്റർ
    • d_size - ഈ ഡാറ്റയുടെ വലിപ്പം (ibid.)
ലൈബ്രറിയിൽ ജോലി പൂർത്തിയാക്കുന്നു
വിഭാഗങ്ങൾ രൂപീകരിച്ചതിന് ശേഷം, നിങ്ങൾക്ക് dwarf_producer_finish ഫംഗ്ഷൻ ഉപയോഗിച്ച് ലിബ്ഡ്വാർഫുമായി പ്രവർത്തിക്കുന്നത് പൂർത്തിയാക്കാൻ കഴിയും:
Dwarf_Unsigned dwarf_producer_finish(Dwarf_P_Debug dbg, Dwarf_Error* error)
ഫംഗ്‌ഷൻ പിശകിൽ DW_DLV_NOCOUNT നൽകുന്നു.
ഈ ഘട്ടത്തിൽ ഡിസ്കിലേക്കുള്ള റെക്കോർഡിംഗ് നടക്കുന്നില്ല എന്നത് ശ്രദ്ധിക്കുക. "ELF സൃഷ്‌ടിക്കുന്നു - ഒരു ഫയൽ എഴുതുന്നു" എന്ന വിഭാഗത്തിൽ നിന്നുള്ള പ്രവർത്തനങ്ങൾ ഉപയോഗിച്ചാണ് റെക്കോർഡിംഗ് നടത്തേണ്ടത്.

ഉപസംഹാരം

അത്രയേയുള്ളൂ.
ഞാൻ ആവർത്തിക്കുന്നു, ഡീബഗ്ഗിംഗ് വിവരങ്ങൾ സൃഷ്ടിക്കുന്നത് വളരെ വിശാലമായ വിഷയമാണ്, മാത്രമല്ല ഞാൻ പല വിഷയങ്ങളിലും സ്പർശിച്ചിട്ടില്ല, മൂടുപടം ഉയർത്തുക മാത്രമാണ് ചെയ്യുന്നത്. ആഗ്രഹിക്കുന്നവർക്ക് അനന്തമായി ആഴത്തിൽ പോകാം.
നിങ്ങൾക്ക് എന്തെങ്കിലും ചോദ്യങ്ങളുണ്ടെങ്കിൽ, ഞാൻ അവയ്ക്ക് ഉത്തരം നൽകാൻ ശ്രമിക്കും.

ELF ഫോർമാറ്റ്

ELF ഫോർമാറ്റിന് നിരവധി ഫയൽ തരങ്ങളുണ്ട്, എക്സിക്യൂട്ടബിൾ ഫയൽ അല്ലെങ്കിൽ ഒബ്ജക്റ്റ് ഫയൽ പോലെ ഞങ്ങൾ ഇതുവരെ വ്യത്യസ്തമായി വിളിച്ചിട്ടുണ്ട്. എന്നിരുന്നാലും, ELF സ്റ്റാൻഡേർഡ് ഇനിപ്പറയുന്ന തരങ്ങളെ വേർതിരിക്കുന്നു:

1. ഫയൽ നീക്കണം(സ്ഥലംമാറ്റാവുന്ന ഫയൽ) മറ്റ് ഒബ്ജക്റ്റ് ഫയലുകളിലേക്ക് ലിങ്ക് ചെയ്യാവുന്ന നിർദ്ദേശങ്ങളും ഡാറ്റയും സംഭരിക്കുന്നു. അത്തരം ലിങ്കിംഗിന്റെ ഫലം എക്സിക്യൂട്ടബിൾ ഫയലോ പങ്കിട്ട ഒബ്‌ജക്റ്റ് ഫയലോ ആകാം.

2. പങ്കിട്ട ഒബ്‌ജക്റ്റ് ഫയൽ(പങ്കിട്ട ഒബ്‌ജക്റ്റ് ഫയൽ) നിർദ്ദേശങ്ങളും ഡാറ്റയും ഉൾക്കൊള്ളുന്നു, പക്ഷേ രണ്ട് തരത്തിൽ ഉപയോഗിക്കാം. ആദ്യ സന്ദർഭത്തിൽ, മാറ്റിസ്ഥാപിക്കാവുന്ന മറ്റ് ഫയലുകളിലേക്കും പങ്കിട്ട ഒബ്‌ജക്റ്റ് ഫയലുകളിലേക്കും ഇത് ലിങ്കുചെയ്യാനാകും, അതിന്റെ ഫലമായി ഒരു പുതിയ ഒബ്‌ജക്റ്റ് ഫയൽ സൃഷ്‌ടിക്കപ്പെടും. രണ്ടാമത്തെ സാഹചര്യത്തിൽ, എക്സിക്യൂഷനുവേണ്ടി ഒരു പ്രോഗ്രാം സമാരംഭിക്കുമ്പോൾ, ഓപ്പറേറ്റിംഗ് സിസ്റ്റത്തിന് അത് പ്രോഗ്രാമിന്റെ എക്സിക്യൂട്ടബിൾ ഫയലുമായി ചലനാത്മകമായി ലിങ്ക് ചെയ്യാൻ കഴിയും, അതിന്റെ ഫലമായി പ്രോഗ്രാമിന്റെ എക്സിക്യൂട്ടബിൾ ഇമേജ് സൃഷ്ടിക്കപ്പെടും. പിന്നീടുള്ള സന്ദർഭത്തിൽ നമ്മൾ സംസാരിക്കുന്നത് പങ്കിട്ട ലൈബ്രറികളെക്കുറിച്ചാണ്.

3. എക്സിക്യൂട്ടബിൾ ഫയൽപ്രക്രിയയുടെ ഒരു ഇമേജ് സൃഷ്ടിക്കാൻ സിസ്റ്റത്തെ അനുവദിക്കുന്ന ഒരു പൂർണ്ണമായ വിവരണം സംഭരിക്കുന്നു. നിർദ്ദേശങ്ങൾ, ഡാറ്റ, ആവശ്യമായ പങ്കിട്ട ഒബ്‌ജക്റ്റ് ഫയലുകളുടെ വിവരണങ്ങൾ, ആവശ്യമായ പ്രതീകാത്മകവും ഡീബഗ്ഗിംഗ് വിവരങ്ങളും ഇതിൽ അടങ്ങിയിരിക്കുന്നു.

ചിത്രത്തിൽ. 2.4 എക്സിക്യൂട്ടബിൾ ഫയലിന്റെ ഘടന കാണിക്കുന്നു, അതിന്റെ സഹായത്തോടെ ഓപ്പറേറ്റിംഗ് സിസ്റ്റത്തിന് ഒരു പ്രോഗ്രാം ഇമേജ് സൃഷ്ടിക്കാനും നിർവ്വഹണത്തിനായി പ്രോഗ്രാം സമാരംഭിക്കാനും കഴിയും.

അരി. 2.4. ELF ഫോർമാറ്റിലുള്ള എക്സിക്യൂട്ടബിൾ ഫയലിന്റെ ഘടന

ഫയലിൽ ഹെഡ്ഡറിന് ഒരു നിശ്ചിത സ്ഥാനമുണ്ട്. ഹെഡറിൽ സംഭരിച്ചിരിക്കുന്ന വിവരങ്ങൾ അനുസരിച്ച് ശേഷിക്കുന്ന ഘടകങ്ങൾ സ്ഥാപിച്ചിരിക്കുന്നു. അതിനാൽ, ഹെഡ്ഡറിൽ ഫയൽ ഘടന, വ്യക്തിഗത ഘടകങ്ങളുടെ സ്ഥാനം, അവയുടെ വലുപ്പങ്ങൾ എന്നിവയുടെ പൊതുവായ വിവരണം അടങ്ങിയിരിക്കുന്നു.

ഒരു ELF ഫയലിന്റെ തലക്കെട്ട് അതിന്റെ ഘടന നിർണ്ണയിക്കുന്നതിനാൽ, നമുക്ക് അത് കൂടുതൽ വിശദമായി നോക്കാം (പട്ടിക 2.4).

പട്ടിക 2.3. ELF ഹെഡർ ഫീൽഡുകൾ

ഫീൽഡ് വിവരണം
e_ident ബൈറ്റുകളുടെ ഒരു നിര, അവയിൽ ഓരോന്നും ഫയലിന്റെ പൊതുവായ ചില സവിശേഷതകൾ നിർവചിക്കുന്നു: ഫയൽ ഫോർമാറ്റ് (ELF), പതിപ്പ് നമ്പർ, സിസ്റ്റം ആർക്കിടെക്ചർ (32-ബിറ്റ് അല്ലെങ്കിൽ 64-ബിറ്റ്) മുതലായവ.
ഇ_തരം ELF ഫോർമാറ്റ് ഒന്നിലധികം തരങ്ങളെ പിന്തുണയ്ക്കുന്നതിനാൽ ഫയൽ തരം
ഇ_മെഷീൻ ഈ ഫയൽ സൃഷ്‌ടിച്ച ഹാർഡ്‌വെയർ പ്ലാറ്റ്‌ഫോമിന്റെ ആർക്കിടെക്ചർ. പട്ടികയിൽ 2.4 ഈ ഫീൽഡിന്റെ സാധ്യമായ മൂല്യങ്ങൾ കാണിക്കുന്നു
ഇ_പതിപ്പ് ELF ഫോർമാറ്റ് പതിപ്പ് നമ്പർ. സാധാരണ EV_CURRENC (നിലവിലെ) എന്ന് നിർവചിച്ചിരിക്കുന്നത്, അതായത് ഏറ്റവും പുതിയ പതിപ്പ് എന്നാണ്
ഇ_പ്രവേശനം പ്രോഗ്രാം ലോഡ് ചെയ്ത ശേഷം സിസ്റ്റം നിയന്ത്രണം കൈമാറുന്ന വെർച്വൽ വിലാസം (എൻട്രി പോയിന്റ്)
ഇ_ഫോഫ് പ്രോഗ്രാം ഹെഡർ പട്ടികയുടെ സ്ഥാനം (ഫയലിന്റെ തുടക്കത്തിൽ നിന്ന് ഓഫ്‌സെറ്റ്).
ഇ_ഷോഫ് വിഭാഗം തലക്കെട്ട് പട്ടിക സ്ഥാനം
e_ehsize തലക്കെട്ടിന്റെ വലിപ്പം
e_phentsize ഓരോ പ്രോഗ്രാം ഹെഡറിന്റെയും വലിപ്പം
e_phnum പ്രോഗ്രാം ഹെഡറുകളുടെ എണ്ണം
e_shentsize ഓരോ സെഗ്‌മെന്റ് തലക്കെട്ടിന്റെയും വലുപ്പം (വിഭാഗം)
e_shnum സെഗ്‌മെന്റ് തലക്കെട്ടുകളുടെ എണ്ണം (വിഭാഗങ്ങൾ)
e_shstrndx സ്ട്രിംഗ് ടേബിൾ അടങ്ങുന്ന സെഗ്‌മെന്റിന്റെ സ്ഥാനം

പട്ടിക 2.4. ELF ഫയൽ ഹെഡർ e_machine ഫീൽഡ് മൂല്യങ്ങൾ

അർത്ഥം ഹാർഡ്വെയർ പ്ലാറ്റ്ഫോം
EM_M32 AT&T WE 32100
EM_SPARC സൺ സ്പാർക്
EM_386 ഇന്റൽ 80386
EM_68K മോട്ടറോള 68000
EM_88K മോട്ടറോള 88000
EM_486 ഇന്റൽ 80486
EM_860 ഇന്റൽ i860
EM_MIPS MIPS RS3000 ബിഗ്-എൻഡിയൻ
EM_MIPS_RS3_LE MIPS RS3000 ലിറ്റിൽ-എൻഡിയൻ
EM_RS6000 6000 രൂപ
EM_PA_RISC PA-RISC
EM_nCUBE nCUBE
EM_VPP500 ഫുജിത്സു VPP500
EM_SPARC32PLUS Sun SPARC 32+

സെഗ്‌മെന്റുകളിൽ നിന്ന് ഒരു പ്രോസസ്സ് ഇമേജ് എങ്ങനെ സൃഷ്ടിക്കാമെന്ന് പ്രോഗ്രാം ഹെഡർ ടേബിളിൽ അടങ്ങിയിരിക്കുന്ന വിവരങ്ങൾ കേർണലിനോട് പറയുന്നു. മിക്ക സെഗ്‌മെന്റുകളും മെമ്മറിയിലേക്ക് പകർത്തി (മാപ്പ് ചെയ്‌തിരിക്കുന്നു) കൂടാതെ കോഡ് അല്ലെങ്കിൽ ഡാറ്റ സെഗ്‌മെന്റുകൾ പോലെ അത് എക്‌സിക്യൂട്ട് ചെയ്യുന്ന പ്രക്രിയയുടെ പ്രസക്തമായ സെഗ്‌മെന്റുകളെ പ്രതിനിധീകരിക്കുന്നു.

ഓരോ പ്രോഗ്രാം സെഗ്‌മെന്റ് തലക്കെട്ടും ഒരു സെഗ്‌മെന്റിനെ വിവരിക്കുകയും ഇനിപ്പറയുന്ന വിവരങ്ങൾ അടങ്ങിയിരിക്കുകയും ചെയ്യുന്നു:

ഈ സെഗ്‌മെന്റിനൊപ്പം സെഗ്‌മെന്റ് തരവും ഓപ്പറേറ്റിംഗ് സിസ്റ്റം പ്രവർത്തനങ്ങളും

ഫയലിലെ സെഗ്മെന്റ് ലൊക്കേഷൻ

പ്രോസസ്സിന്റെ വെർച്വൽ മെമ്മറിയിലെ സെഗ്‌മെന്റിന്റെ ആരംഭ വിലാസം

ഫയലിലെ സെഗ്‌മെന്റ് വലുപ്പം

മെമ്മറി സെഗ്മെന്റ് വലുപ്പം

സെഗ്മെന്റ് ആക്സസ് ഫ്ലാഗുകൾ (എഴുതുക, വായിക്കുക, നടപ്പിലാക്കുക)

ചില സെഗ്‌മെന്റുകൾ LOAD തരത്തിലാണ്, അത് എക്‌സിക്യൂഷനുള്ള പ്രോഗ്രാം ആരംഭിക്കുമ്പോൾ, ഈ സെഗ്‌മെന്റുകൾക്ക് അനുയോജ്യമായ ഡാറ്റാ ഘടനകൾ സൃഷ്ടിക്കാൻ കേർണലിനോട് നിർദ്ദേശിക്കുന്നു. പ്രദേശങ്ങൾ, ഒരു പ്രക്രിയയുടെ വെർച്വൽ മെമ്മറിയുടെ തുടർച്ചയായ വിഭാഗങ്ങളും അവയുമായി ബന്ധപ്പെട്ട ആട്രിബ്യൂട്ടുകളും ഇത് നിർവചിക്കുന്നു. സെഗ്‌മെന്റ്, ELF ഫയലിലെ സ്ഥാനം അനുബന്ധ പ്രോഗ്രാം ഹെഡറിൽ സൂചിപ്പിച്ചിരിക്കുന്നു, സൃഷ്ടിച്ച ഏരിയയിലേക്ക് മാപ്പ് ചെയ്യും, അതിന്റെ തുടക്കത്തിന്റെ വെർച്വൽ വിലാസം പ്രോഗ്രാം ഹെഡറിലും സൂചിപ്പിച്ചിരിക്കുന്നു. ഈ തരത്തിലുള്ള സെഗ്‌മെന്റുകളിൽ, ഉദാഹരണത്തിന്, പ്രോഗ്രാം നിർദ്ദേശങ്ങളും (കോഡ്) അതിന്റെ ഡാറ്റയും അടങ്ങിയിരിക്കുന്ന സെഗ്‌മെന്റുകൾ ഉൾപ്പെടുന്നു. സെഗ്‌മെന്റ് വലുപ്പം ഏരിയ വലുപ്പത്തേക്കാൾ ചെറുതാണെങ്കിൽ, ഉപയോഗിക്കാത്ത ഇടം പൂജ്യങ്ങൾ കൊണ്ട് നിറച്ചേക്കാം. അൺഇനീഷ്യലൈസ്ഡ് പ്രോസസ്സ് ഡാറ്റ (ബിഎസ്എസ്) സൃഷ്ടിക്കുമ്പോൾ ഈ സംവിധാനം പ്രത്യേകിച്ചും ഉപയോഗിക്കുന്നു. ഞങ്ങൾ അധ്യായം 3-ൽ മേഖലകളെക്കുറിച്ച് കൂടുതൽ സംസാരിക്കും.

INTERP സെഗ്‌മെന്റ് പ്രോഗ്രാം ഇന്റർപ്രെറ്ററിനെ സംഭരിക്കുന്നു. ഡൈനാമിക് ലിങ്കിംഗ് ആവശ്യമുള്ള പ്രോഗ്രാമുകൾക്കായി ഈ സെഗ്മെന്റ് തരം ഉപയോഗിക്കുന്നു. ഡൈനാമിക് ലിങ്കിംഗിന്റെ സാരാംശം, എക്സിക്യൂട്ടബിൾ ഫയലിന്റെ (പങ്കിട്ട ഒബ്ജക്റ്റ് ഫയലുകൾ) വ്യക്തിഗത ഘടകങ്ങൾ ബന്ധിപ്പിച്ചിരിക്കുന്നത് കംപൈലേഷൻ ഘട്ടത്തിലല്ല, മറിച്ച് നിർവ്വഹണത്തിനായി പ്രോഗ്രാം സമാരംഭിക്കുന്ന ഘട്ടത്തിലാണ്. ഫയലിന്റെ പേര് ഡൈനാമിക് ലിങ്ക് എഡിറ്റർ, ഈ സെഗ്മെന്റിൽ സംഭരിച്ചിരിക്കുന്നു. നിർവ്വഹണത്തിനായി ഒരു പ്രോഗ്രാം സമാരംഭിക്കുമ്പോൾ, നിർദ്ദിഷ്ട ലിങ്ക് എഡിറ്റർ ഉപയോഗിച്ച് കേർണൽ ഒരു പ്രോസസ്സ് ഇമേജ് സൃഷ്ടിക്കുന്നു. അതിനാൽ, തുടക്കത്തിൽ ഇത് മെമ്മറിയിലേക്ക് ലോഡ് ചെയ്യുന്നത് ഉറവിട പ്രോഗ്രാമല്ല, ഡൈനാമിക് ലിങ്ക് എഡിറ്ററാണ്. അടുത്ത ഘട്ടത്തിൽ, എക്സിക്യൂട്ടബിൾ ഫയലിന്റെ പൂർണ്ണമായ ഒരു ഇമേജ് സൃഷ്ടിക്കുന്നതിന് ഡൈനാമിക് ലിങ്ക് എഡിറ്റർ UNIX കേർണലുമായി പ്രവർത്തിക്കുന്നു. ഡൈനാമിക് എഡിറ്റർ ആവശ്യമായ പങ്കിട്ട ഒബ്‌ജക്റ്റ് ഫയലുകൾ ലോഡ് ചെയ്യുന്നു, അവയുടെ പേരുകൾ സോഴ്‌സ് എക്‌സിക്യൂട്ടബിൾ ഫയലിന്റെ പ്രത്യേക സെഗ്‌മെന്റുകളിൽ സംഭരിക്കുകയും ആവശ്യമായ പ്ലേസ്‌മെന്റും ലിങ്കിംഗും നടത്തുകയും ചെയ്യുന്നു. അവസാനം, നിയന്ത്രണം യഥാർത്ഥ പ്രോഗ്രാമിലേക്ക് മാറ്റുന്നു.

അവസാനമായി, ഫയൽ ഒരു തലക്കെട്ട് പട്ടികയിൽ അവസാനിക്കുന്നു വിഭാഗങ്ങൾഅഥവാ വിഭാഗങ്ങൾ(വിഭാഗം). കംപൈലേഷൻ സമയത്തോ ഡൈനാമിക് ലിങ്കിംഗ് സമയത്തോ മറ്റ് മൊഡ്യൂളുകളുമായി ലിങ്ക് ചെയ്യാൻ ഉപയോഗിക്കുന്ന ഫയലിന്റെ വിഭാഗങ്ങളെ വിഭാഗങ്ങൾ (വിഭാഗങ്ങൾ) നിർവ്വചിക്കുന്നു. അതനുസരിച്ച്, ഈ വിഭാഗങ്ങൾ വിവരിക്കുന്നതിന് ആവശ്യമായ എല്ലാ വിവരങ്ങളും തലക്കെട്ടുകളിൽ അടങ്ങിയിരിക്കുന്നു. ചട്ടം പോലെ, വിഭാഗങ്ങളിൽ സെഗ്മെന്റുകളെക്കുറിച്ചുള്ള കൂടുതൽ വിശദമായ വിവരങ്ങൾ അടങ്ങിയിരിക്കുന്നു. ഉദാഹരണത്തിന്, പ്രോഗ്രാമിൽ ഉപയോഗിക്കുന്ന ചിഹ്നങ്ങളുടെ സൂചികകൾ സംഭരിക്കുന്നതിനുള്ള ഒരു ഹാഷ് ടേബിൾ, പ്രോഗ്രാമിന്റെ ഇനീഷ്യലൈസേഷൻ കോഡിന്റെ ഒരു വിഭാഗം, ഡൈനാമിക് എഡിറ്റർ ഉപയോഗിക്കുന്ന ലിങ്കിംഗ് ടേബിൾ, യഥാർത്ഥമായത് ഉൾക്കൊള്ളുന്ന ഒരു വിഭാഗം എന്നിങ്ങനെ നിരവധി വിഭാഗങ്ങൾ ഒരു കോഡ് സെഗ്‌മെന്റിൽ അടങ്ങിയിരിക്കാം. പ്രോഗ്രാം നിർദ്ദേശങ്ങൾ.

പ്രോസസ് വെർച്വൽ മെമ്മറിയുടെ ഓർഗനൈസേഷനെക്കുറിച്ച് ചർച്ച ചെയ്യുമ്പോൾ ഞങ്ങൾ അദ്ധ്യായം 3-ലെ ELF ഫോർമാറ്റിലേക്ക് മടങ്ങും, എന്നാൽ ഇപ്പോൾ ഞങ്ങൾ അടുത്ത പൊതുവായ ഫോർമാറ്റായ COFF-ലേക്ക് പോകും.

യുണിക്സിനായുള്ള ആർട്ട് ഓഫ് പ്രോഗ്രാമിംഗ് എന്ന പുസ്തകത്തിൽ നിന്ന് രചയിതാവ് റെയ്മണ്ട് എറിക് സ്റ്റീഫൻ

ഒരു കമ്പ്യൂട്ടറിൽ പ്രവർത്തിക്കുന്നതിനുള്ള സ്വയം നിർദ്ദേശ മാനുവൽ എന്ന പുസ്തകത്തിൽ നിന്ന് രചയിതാവ് കോലിസ്നിചെങ്കോ ഡെനിസ് നിക്കോളാവിച്ച്

അബ്‌സ്‌ട്രാക്റ്റ്, കോഴ്‌സ് വർക്ക്, കമ്പ്യൂട്ടറിലെ ഡിപ്ലോമ എന്ന പുസ്തകത്തിൽ നിന്ന് രചയിതാവ് Balovsyak Nadezhda Vasilievna

5.2.6. Windows INI ഫോർമാറ്റ് പല Microsoft Windows പ്രോഗ്രാമുകളും ഉദാഹരണം 5.6-ൽ കാണിച്ചിരിക്കുന്നതുപോലെയുള്ള ഒരു ടെക്സ്റ്റ് ഡാറ്റ ഫോർമാറ്റ് ഉപയോഗിക്കുന്നു. അക്കൗണ്ട്, ഡയറക്‌ടറി, numeric_id, ഡെവലപ്പർ എന്നിങ്ങനെ പേരുള്ള ഓപ്‌ഷണൽ റിസോഴ്‌സുകളെ പൈത്തൺ, എസ്എൻജി, ഫെച്ച്‌മെയിൽ, പൈ-ഹൗട്ടോ എന്നിങ്ങനെ പേരുള്ള പ്രോജക്‌റ്റുകളുമായി ഈ ഉദാഹരണം ബന്ധപ്പെടുത്തുന്നു. റെക്കോർഡിംഗിൽ

ഒരു കമ്പ്യൂട്ടറിൽ പ്രവർത്തിക്കുന്നതിനുള്ള ഏറ്റവും പുതിയ സ്വയം നിർദ്ദേശ മാനുവൽ എന്ന പുസ്തകത്തിൽ നിന്ന് രചയിതാവ് ബെലുണ്ട്സോവ് വലേരി

14.5.3. സെൽ ഫോർമാറ്റ് സെല്ലിന്റെ മൂല്യം എങ്ങനെ പ്രദർശിപ്പിക്കുമെന്ന് ഫോർമാറ്റ് വ്യക്തമാക്കുന്നു. ഫോർമാറ്റ് സെല്ലിന്റെ ഡാറ്റ തരവുമായി അടുത്ത ബന്ധപ്പെട്ടിരിക്കുന്നു. നിങ്ങൾ സ്വയം തരം സജ്ജമാക്കുക. നിങ്ങൾ ഒരു നമ്പർ നൽകിയിട്ടുണ്ടെങ്കിൽ, അത് ഒരു സംഖ്യാ ഡാറ്റാ തരമാണ്. ഡാറ്റ തരം അടിസ്ഥാനമാക്കി ഫോർമാറ്റ് നിർണ്ണയിക്കാൻ Excel തന്നെ ശ്രമിക്കുന്നു. ഉദാഹരണത്തിന്, നിങ്ങൾ ടെക്സ്റ്റ് നൽകിയിട്ടുണ്ടെങ്കിൽ, തുടർന്ന്

യുണിക്സിനായുള്ള ആർട്ട് ഓഫ് പ്രോഗ്രാമിംഗ് എന്ന പുസ്തകത്തിൽ നിന്ന് രചയിതാവ് റെയ്മണ്ട് എറിക് സ്റ്റീഫൻ

PDF ഫോർമാറ്റ് PDF എന്നത് പോർട്ടബിൾ ഡോക്യുമെന്റ് ഫോർമാറ്റിനെ സൂചിപ്പിക്കുന്നു. ഫയലുകളിൽ വിവരങ്ങൾ പ്രദർശിപ്പിക്കുന്നതിലെ പ്രശ്നങ്ങൾ ഇല്ലാതാക്കുന്നതിനാണ് ഈ ഫോർമാറ്റ് പ്രത്യേകമായി സൃഷ്ടിച്ചത്. അതിന്റെ പ്രയോജനം, ഒന്നാമതായി, PDF ഫോർമാറ്റിൽ സംരക്ഷിച്ചിരിക്കുന്ന ഒരു പ്രമാണം സമാനമായിരിക്കും

TCP/IP ആർക്കിടെക്ചർ, പ്രോട്ടോക്കോളുകൾ, നടപ്പിലാക്കൽ (IP പതിപ്പ് 6, IP സുരക്ഷ എന്നിവ ഉൾപ്പെടെ) എന്ന പുസ്തകത്തിൽ നിന്ന് ഫെയ്ത്ത് സിഡ്നി എം

ഫയൽ ഫോർമാറ്റ് ഒരു ഉപയോക്താവ് ഒരു ഫയലുമായി പ്രവർത്തിക്കാൻ തുടങ്ങുമ്പോൾ, അത് ഏത് ഫോർമാറ്റിലാണ് എഴുതിയതെന്നും ഏത് പ്രോഗ്രാമിലാണ് അത് തുറക്കേണ്ടതെന്നും സിസ്റ്റം അറിയേണ്ടതുണ്ട്. ഉദാഹരണത്തിന്, ഒരു ഫയലിൽ പ്ലെയിൻ ടെക്സ്റ്റ് അടങ്ങിയിട്ടുണ്ടെങ്കിൽ, അത് ഏത് ടെക്സ്റ്റ് പ്രോഗ്രാമിലും വായിക്കാൻ കഴിയും

എല്ലാവർക്കും വേണ്ടി Yandex എന്ന പുസ്തകത്തിൽ നിന്ന് രചയിതാവ് അബ്രാംസൺ എം.ജി.

5.2.2. RFC 822 ഫോർമാറ്റ് ഇന്റർനെറ്റ് ഇ-മെയിൽ സന്ദേശങ്ങളുടെ ടെക്സ്റ്റ് ഫോർമാറ്റിൽ നിന്നാണ് RFC 822 മെറ്റാ ഫോർമാറ്റ് ഉരുത്തിരിഞ്ഞത്. ഈ ഫോർമാറ്റ് വിവരിക്കുന്ന പ്രധാന ഇന്റർനെറ്റ് RFC സ്റ്റാൻഡേർഡ് RFC 822 ആണ് (പിന്നീട് RFC 2822 മാറ്റി). MIME (മൾട്ടിപർപ്പസ് ഇന്റർനെറ്റ് മീഡിയ എക്സ്റ്റൻഷൻ) ഫോർമാറ്റ്

Macromedia Flash Professional എന്ന പുസ്തകത്തിൽ നിന്ന് 8. ഗ്രാഫിക്സും ആനിമേഷനും രചയിതാവ് ഡ്രോണോവ് വി.എ.

5.2.3. കുക്കി-ജാർ ഫോർമാറ്റ് കുക്കി-ജാർ ഫോർമാറ്റ് റാൻഡം ഉദ്ധരണികളുടെ സ്വന്തം ഡാറ്റാബേസിനായി ഫോർച്യൂൺ(1) ഉപയോഗിക്കുന്നു. ഘടനയില്ലാത്ത ടെക്‌സ്‌റ്റിന്റെ ബ്ലോക്കുകളുള്ള പോസ്റ്റുകൾക്ക് ഇത് അനുയോജ്യമാണ്. ഈ ഫോർമാറ്റിൽ റെക്കോർഡ് സെപ്പറേറ്ററായി ചിഹ്നം ഉപയോഗിക്കുന്നു

കമ്പ്യൂട്ടർ സൗണ്ട് പ്രോസസ്സിംഗ് എന്ന പുസ്തകത്തിൽ നിന്ന് രചയിതാവ് സാഗുമെനോവ് അലക്സാണ്ടർ പെട്രോവിച്ച്

5.2.4. റെക്കോർഡ്-ജാർ ഫോർമാറ്റ് കുക്കി-ജാർ ഫോർമാറ്റ് റെക്കോർഡ് സെപ്പറേറ്ററുകൾ റെക്കോർഡുകൾക്കായുള്ള RFC 822 രൂപക ഫോർമാറ്റിനൊപ്പം നന്നായി പ്രവർത്തിക്കുന്നു, ഈ പുസ്തകത്തിൽ "റെക്കോർഡ്-ജാർ" എന്നൊരു ഫോർമാറ്റ് രൂപീകരിക്കുന്നു. ചില സമയങ്ങളിൽ വ്യത്യസ്തമായ വ്യക്തമായ പേരുകളുള്ള ഒന്നിലധികം എൻട്രികളെ പിന്തുണയ്ക്കുന്ന ഒരു ടെക്സ്റ്റ് ഫോർമാറ്റ് ആവശ്യമാണ്

യുണിക്സ് ഓപ്പറേറ്റിംഗ് സിസ്റ്റം എന്ന പുസ്തകത്തിൽ നിന്ന് രചയിതാവ് റോബചെവ്സ്കി ആൻഡ്രി എം.

5.2.6. Windows INI ഫോർമാറ്റ് പല Microsoft Windows പ്രോഗ്രാമുകളും ഉദാഹരണം 5.6-ൽ കാണിച്ചിരിക്കുന്നതുപോലെയുള്ള ഒരു ടെക്സ്റ്റ് ഡാറ്റ ഫോർമാറ്റ് ഉപയോഗിക്കുന്നു. അക്കൗണ്ട്, ഡയറക്‌ടറി, numeric_id, ഡെവലപ്പർ എന്നിങ്ങനെ പേരുള്ള ഓപ്‌ഷണൽ റിസോഴ്‌സുകളെ പൈത്തൺ, എസ്എൻജി, ഫെച്ച്‌മെയിൽ, പൈ-ഹൗട്ടോ എന്നിങ്ങനെ പേരുള്ള പ്രോജക്‌റ്റുകളുമായി ഈ ഉദാഹരണം ബന്ധപ്പെടുത്തുന്നു. റെക്കോർഡിംഗിൽ

സ്ത്രീകൾക്കുള്ള ഓഫീസ് കമ്പ്യൂട്ടർ എന്ന പുസ്തകത്തിൽ നിന്ന് രചയിതാവ് പാസ്റ്റെർനാക്ക് എവ്ജീനിയ

19.5 പൊതുവൽക്കരിച്ച URL ഫോർമാറ്റ് മുകളിൽ പറഞ്ഞവ സംഗ്രഹിക്കാൻ, ഞങ്ങൾ ശ്രദ്ധിക്കുന്നത്:? ഉപയോഗിച്ച ആക്സസ് പ്രോട്ടോക്കോൾ ഉപയോഗിച്ചാണ് URL ആരംഭിക്കുന്നത്.? ഓൺലൈൻ വാർത്തകളും ഇമെയിലും ഒഴികെയുള്ള എല്ലാ ആപ്ലിക്കേഷനുകൾക്കും, ഇനിപ്പറയുന്ന സെപ്പറേറ്റർ പിന്തുടരുന്നു: //.? അപ്പോൾ സെർവറിന്റെ ഹോസ്റ്റ് നാമം വ്യക്തമാക്കിയിരിക്കുന്നു.? ഒടുവിൽ

രചയിതാവിന്റെ പുസ്തകത്തിൽ നിന്ന്

3.3.1. RSS ഫോർമാറ്റ് നിങ്ങൾക്ക് വെബ്‌സൈറ്റ് വാർത്തകൾ വ്യത്യസ്ത രീതികളിൽ വായിക്കാം. ഇടയ്ക്കിടെ സൈറ്റ് സന്ദർശിക്കുകയും പുതിയ സന്ദേശങ്ങൾ നോക്കുകയും ചെയ്യുക എന്നതാണ് ഏറ്റവും എളുപ്പമുള്ള മാർഗം. ഒരു വാർത്താ ചാനലുമായി ബന്ധിപ്പിക്കുന്നതും തലക്കെട്ടുകളോ വാർത്താ സംഗ്രഹങ്ങളോ ലഭിക്കുന്നതുമായ ഒരു പ്രോഗ്രാം നിങ്ങൾക്ക് ഇൻസ്റ്റാൾ ചെയ്യാൻ കഴിയും

രചയിതാവിന്റെ പുസ്തകത്തിൽ നിന്ന്

MP3 ഫോർമാറ്റ് MP3 ഫോർമാറ്റ് MPEG 1 ലെവൽ 3 കോഡെക് ഉപയോഗിച്ച് കംപ്രസ്സുചെയ്‌ത സംഗീത ഫയലുകൾ വിതരണം ചെയ്യുന്നതിനായി സൃഷ്ടിച്ചതാണ്. നിലവിൽ, ഇന്റർനെറ്റിലൂടെ മാത്രമല്ല, സംഗീതം വിതരണം ചെയ്യുന്നതിനുള്ള ഏറ്റവും ജനപ്രിയ ഫോർമാറ്റാണിത്. എല്ലാ ഓഡിയോ റെക്കോർഡിംഗും പ്രോസസ്സിംഗ് പ്രോഗ്രാമുകളും പിന്തുണയ്ക്കുന്നു

രചയിതാവിന്റെ പുസ്തകത്തിൽ നിന്ന്

MP3 ഫോർമാറ്റ് ഒരു ഓഡിയോ കംപ്രഷൻ രീതി, അതുപോലെ തന്നെ പെർസെപ്ച്വൽ ഓഡിയോ കോഡിംഗിനെ അടിസ്ഥാനമാക്കി MPEG (മൂവിംഗ് പിക്ചേഴ്സ് എക്സ്പെർട്ട്സ് ഗ്രൂപ്പ്) എന്ന അന്താരാഷ്ട്ര സംഘടന നിർദ്ദേശിച്ച കംപ്രസ് ചെയ്ത ഓഡിയോ ഫയൽ ഫോർമാറ്റും. കാര്യക്ഷമമായ കോഡിംഗ് അൽഗോരിതങ്ങൾ സൃഷ്ടിക്കുന്നതിൽ പ്രവർത്തിക്കുക

രചയിതാവിന്റെ പുസ്തകത്തിൽ നിന്ന്

ELF ഫോർമാറ്റ് ELF ഫോർമാറ്റിന് നിരവധി ഫയൽ തരങ്ങളുണ്ട്, എക്സിക്യൂട്ടബിൾ ഫയൽ അല്ലെങ്കിൽ ഒബ്ജക്റ്റ് ഫയൽ പോലെ ഞങ്ങൾ ഇതുവരെ വ്യത്യസ്ത പേരുകളിൽ വിളിച്ചിട്ടുണ്ട്. എന്നിരുന്നാലും, ELF സ്റ്റാൻഡേർഡ് ഇനിപ്പറയുന്ന തരങ്ങളെ വേർതിരിക്കുന്നു:1. സാധ്യമായ നിർദ്ദേശങ്ങളും ഡാറ്റയും സംഭരിക്കുന്ന ഒരു സ്ഥലം മാറ്റാവുന്ന ഫയൽ

രചയിതാവിന്റെ പുസ്തകത്തിൽ നിന്ന്

നമ്പർ ഫോർമാറ്റ് ഞങ്ങൾ ഒടുവിൽ നമ്പർ ഫോർമാറ്റിൽ എത്തി. ഞാൻ ഇതിനകം ഒന്നിലധികം തവണ ഇത് സൂചിപ്പിച്ചിട്ടുണ്ട്, ഇപ്പോൾ ഞാൻ അത് തകർക്കും (നിങ്ങൾക്ക് ഇതിനകം പൊതുവായ അർത്ഥം മനസ്സിലായിട്ടുണ്ടെങ്കിലും). Excel-ലെ നമ്പറുകൾ വിവിധ ഫോർമാറ്റുകളിൽ പ്രദർശിപ്പിക്കാൻ കഴിയും. ഈ വിഭാഗത്തിൽ ഏത് നമ്പർ ഫോർമാറ്റുകൾ നിലവിലുണ്ടെന്നും എങ്ങനെയെന്നും നമ്മൾ സംസാരിക്കും