秋·风

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
lazarus编写龙芯的lazarus安装工具需要确定当前系统的ABI版本,以下方法可以读取linux执行文件elf的machine和flags信息:
    不同架构在e_machine和e_flags字段有不同值:

    架构          e_machine    e_flags
    x86           3            通常为0
    x86_64        62           通常为0
    ARM           40           ABI、浮点类型等
    AArch64       183          通常为0
    MIPS          8            ABI版本、字节序、架构级别等
    PowerPC       20           通常为0
    RISC-V        243          浮点ABI、扩展指令集等
    Loongarch64   258          ABI版本
        

function GetABIVersion(const FileName: string): string;返回ABI的值

function GetABIVersion(const FileName: string): string;
type
  TElf32_Ehdr = packed record
    e_ident: array[0..15] of Byte;
    e_type: Word;
    e_machine: Word;
    e_version: Cardinal;
    e_entry: Cardinal;
    e_phoff: Cardinal;
    e_shoff: Cardinal;
    e_flags: Cardinal;  // 目标标志字段
    e_ehsize: Word;
    e_phentsize: Word;
    e_phnum: Word;
    e_shentsize: Word;
    e_shnum: Word;
    e_shstrndx: Word;
  end;

  TElf64_Ehdr = packed record
    e_ident: array[0..15] of Byte;
    e_type: Word;
    e_machine: Word;
    e_version: Cardinal;
    e_entry: UInt64;
    e_phoff: UInt64;
    e_shoff: UInt64;
    e_flags: Cardinal;  // 目标标志字段
    e_ehsize: Word;
    e_phentsize: Word;
    e_phnum: Word;
    e_shentsize: Word;
    e_shnum: Word;
    e_shstrndx: Word;
  end;
var
  Fs: TFileStream;
  Ident: array[0..15] of Byte;
  Elf32: TElf32_Ehdr;
  Elf64: TElf64_Ehdr;
  Flags: Cardinal;
  i:Int64;
  cpuname:String;
  abi:String;
begin
  Result := 'Unknown';
  Fs := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
  try
    // 读取 ELF 标识
    Fs.ReadBuffer(Ident, SizeOf(Ident));

    // 验证 ELF 魔数
    if (Ident[0] <> $7F) or (Ident[1] <> Byte('E')) or
       (Ident[2] <> Byte('L')) or (Ident[3] <> Byte('F')) then
    begin
      Exit; // 非 ELF 文件
    end;

    // 读取完整的文件头
    Fs.Position := 0;
    case Ident[4] of // EI_CLASS
      1: begin // ELFCLASS32
        Fs.ReadBuffer(Elf32, SizeOf(Elf32));
        Flags := Elf32.e_flags;
      end;
      2: begin // ELFCLASS64
        Fs.ReadBuffer(Elf64, SizeOf(Elf64));
        Flags := Elf64.e_flags;
      end;
      else Exit;
    end;
    cpuname:= IntToStr(Elf64.e_machine);
    if Elf64.e_machine=3 then
      cpuname:='x86';
    if Elf64.e_machine=62 then
      cpuname:='x86_64';
    if Elf64.e_machine=40 then
      cpuname:='arm';
    if Elf64.e_machine=183 then
      cpuname:='aarch64';
    if Elf64.e_machine=8 then
      cpuname:='mips';
    if Elf64.e_machine=20 then
      cpuname:='PowerPC';
    if Elf64.e_machine=243 then
      cpuname:='risc-v';
    if Elf64.e_machine=258 then
      cpuname:='loongarch64';
    abi:='';
    if Flags=3 then
      abi:='abi 1.0';
    if Flags=$43 then
      abi:='abi 2.0';
    Result:=abi;
  finally
    Fs.Free;
  end;
end;

使用方法:

ShowMessage(GetABIVersion('/bin/ls'));

 

posted on 2025-06-28 15:14  秋·风  阅读(96)  评论(0)    收藏  举报