Skip to content

Commit

Permalink
NonLLVMMisc: Add FileHandling class
Browse files Browse the repository at this point in the history
This class will contain a static method to detect which file we are
dealing with w.r.t ELF files.

Signed-off-by: Marcos Paulo de Souza <mpdesouza@suse.com>
  • Loading branch information
marcosps committed Aug 12, 2024
1 parent 5e762c3 commit bd031b8
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 5 deletions.
21 changes: 16 additions & 5 deletions libcextract/ElfCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,12 +91,23 @@ ElfObject::ElfObject(const char *path)
throw std::runtime_error("ELF file not found: " + parser_path);
}

/* Create libelf object and store it in the class variable. */
ElfObj = elf_begin(ElfFd, ELF_C_READ, nullptr);
if (ElfObj == nullptr) {
enum FileHandling::FileType ft = FileHandling::Get_File_Type(ElfFd);

switch (ft) {
case FileHandling::FILE_TYPE_ELF: {
/* Create libelf object and store it in the class variable. */
ElfObj = elf_begin(ElfFd, ELF_C_READ, nullptr);
if (ElfObj == nullptr) {
close(ElfFd);
throw std::runtime_error("libelf error on file " + parser_path + ": "
+ std::string(elf_errmsg(elf_errno())));
}
break;
}

default:
close(ElfFd);
throw std::runtime_error("libelf error on file " + parser_path + ": "
+ std::string(elf_errmsg(elf_errno())));
throw std::runtime_error("Format not recognized: " + parser_path + "\n");
}
}

Expand Down
35 changes: 35 additions & 0 deletions libcextract/NonLLVMMisc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>

#include <iostream>

/** @brief Handle some quirks of getline. */
char *getline_easy(FILE *file)
Expand Down Expand Up @@ -102,3 +105,35 @@ bool check_color_available(void)
const char *term = getenv("TERM");
return term && strcmp(term, "dumb") != 0 && isatty(STDOUT_FILENO);
}

enum FileHandling::FileType FileHandling::Get_File_Type(int fd)
{

unsigned char buf[4] = { 0 };

int ret = read(fd, buf, 4);
if (ret < 0) {
throw std::runtime_error("error reading ELF file: " + std::to_string(ret));
} else if (ret == 0) {
throw std::runtime_error("error reading ELF file: empty file?");
}

/* reset file pointer */
lseek(fd, 0, SEEK_SET);

const unsigned char elf_magic[4] = { 0x7f, 0x45, 0x4c, 0x46 };
const unsigned char zlib_magic[2] = { 0x1f, 0x8b };
const unsigned char zstd_magic[4] = { 0x28, 0xb5, 0x2f, 0xfd };

/* Check if the file is an ELF */
if (!memcmp(buf, elf_magic, 4))
return FILE_TYPE_ELF;

else if (!memcmp(buf, zlib_magic, 2))
return FILE_TYPE_GZ;

else if (!memcmp(buf, zstd_magic, 4))
return FILE_TYPE_ZSTD;

return FILE_TYPE_UNKNOWN;
}
13 changes: 13 additions & 0 deletions libcextract/NonLLVMMisc.hh
Original file line number Diff line number Diff line change
Expand Up @@ -115,3 +115,16 @@ class VectorRef
T *Ref;
unsigned Size;
};

class FileHandling
{
public:
enum FileType {
FILE_TYPE_ELF,
FILE_TYPE_GZ,
FILE_TYPE_ZSTD,
FILE_TYPE_UNKNOWN,
};

static enum FileType Get_File_Type(int fd);
};

0 comments on commit bd031b8

Please sign in to comment.