readelferislinks utility for parsing ERIS ELF notes

This commit is contained in:
Emery Hemingway 2022-10-12 22:01:01 -05:00
parent 20796fabae
commit 6158b58569
4 changed files with 68 additions and 1 deletions

View File

@ -21,4 +21,4 @@ The format of the CBOR data within the `.note.eris-links` section is a the self-
#6.55799({ * tstr => #6.276(bstr) })
```
At this time of writing there is no utility for dumping the note into a human readable format.
This repository contains a `readelferislinks` utility for extracting the note into a textual format.

View File

@ -214,6 +214,9 @@ in nullPkgs // {
# Patch to fix a bug in rewriting the .dynstr section.
] prev.patchelf;
readelferislinks =
final.nimPackages.callPackage ../packages/readelferislinks { };
rsync = overrideHost {
enableACLs = false;
popt = null;

View File

@ -0,0 +1,17 @@
{ lib, buildNimPackage, cbor, eris }:
buildNimPackage rec {
pname = "readelferislinks";
version = "20221012";
nimBinOnly = true;
src = ./src;
preConfigure = ''
cat << EOF > ${pname}.nimble
bin = @["${pname}"]
EOF
'';
buildInputs = [ cbor eris ];
meta = {
description = "Utility for parsing ERIS links within an ELF binary";
};
}

View File

@ -0,0 +1,47 @@
# SPDX-FileCopyrightText: ☭ 2022 Emery Hemingway
# SPDX-License-Identifier: GPL-3.0-or-later.txt
import std/[os, streams, tables]
import cbor, eris
proc atChar(strm: Stream; c: char): bool =
if strm.atEnd:
quit "reached end of stream without finding ELF note"
c == strm.readChar()
proc scanUntil(strm: Stream; pat: string) =
while true:
block patLoop:
for c in pat:
if not strm.atChar(c): break patLoop
return
proc parseStream(strm: Stream) =
# TODO: write an ELF parser.
strm.scanUntil("Sigil\x00\x00\x00\xD9\xD9\xF7")
# scan for the ELF tag owner and the self-describing CBOR tag
let node = strm.readCbor()
if node.kind == cborUnsigned and node.uint == 0: discard
elif node.kind != cborMap:
quit("unrecognized CBOR data: " & $node)
else:
for key, val in node.map:
if key.kind != cborText or val.kind != cborBytes or not val.hasTag(erisCborTag):
quit("Unrecognized note data " & $node)
let cap = parseCap(val.bytes)
stdout.writeLine cap, " ", key.text
proc main =
var args = commandLineParams()
if args.len == 0:
args.add "-"
for arg in args:
var str =
if arg == "-":
newFileStream(stdin)
else:
openFileStream(arg)
parseStream(str)
close(str)
main()