Skip to content

Commit

Permalink
Avoid memory allocations with new (replaced with smart pointers)
Browse files Browse the repository at this point in the history
  • Loading branch information
Unkorunk committed Nov 8, 2024
1 parent fe3d5de commit 7878943
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 127 deletions.
108 changes: 51 additions & 57 deletions coffi/coffi.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ class coffi : public coffi_strings,
//---------------------------------------------------------------------
coffi()
: coffi_strings{}, architecture_{COFFI_ARCHITECTURE_NONE},
dos_header_{0}, coff_header_{0}, optional_header_{0}, win_header_{0},
dos_header_{}, coff_header_{}, optional_header_{}, win_header_{},
directories_{this}
{
create(COFFI_ARCHITECTURE_PE);
Expand Down Expand Up @@ -119,7 +119,7 @@ class coffi : public coffi_strings,
stream.seekg(0);

architecture_ = COFFI_ARCHITECTURE_NONE;
dos_header_ = new dos_header;
dos_header_ = std::make_unique<dos_header>();
if (dos_header_->load(stream)) {
// It is an EXE
architecture_ = COFFI_ARCHITECTURE_PE;
Expand All @@ -131,7 +131,7 @@ class coffi : public coffi_strings,
}

// Try to read a PE header
coff_header_ = new coff_header_impl;
coff_header_ = std::make_unique<coff_header_impl>();
if (coff_header_->load(stream)) {

// Check the machine
Expand Down Expand Up @@ -180,7 +180,7 @@ class coffi : public coffi_strings,
// Try to read a TI header
if (architecture_ == COFFI_ARCHITECTURE_NONE) {

coff_header_ = new coff_header_impl_ti;
coff_header_ = std::make_unique<coff_header_impl_ti>();
stream.seekg(0);
if (!coff_header_->load(stream)) {
clean();
Expand All @@ -200,7 +200,7 @@ class coffi : public coffi_strings,

if (architecture_ == COFFI_ARCHITECTURE_NONE) {
// The format is not recognized, default to PE format header
coff_header_ = new coff_header_impl;
coff_header_ = std::make_unique<coff_header_impl>();
stream.seekg(0);
if (!coff_header_->load(stream)) {
clean();
Expand All @@ -211,15 +211,15 @@ class coffi : public coffi_strings,
if (coff_header_->get_optional_header_size()) {
if (architecture_ == COFFI_ARCHITECTURE_PE) {
std::streampos pos = stream.tellg();
optional_header_ = new optional_header_impl_pe;
optional_header_ = std::make_unique<optional_header_impl_pe>();
if (!optional_header_->load(stream)) {
clean();
return false;
}
if (optional_header_->get_magic() == OH_MAGIC_PE32PLUS) {
delete optional_header_;
optional_header_.reset();
stream.seekg(pos);
optional_header_ = new optional_header_impl_pe_plus;
optional_header_ = std::make_unique<optional_header_impl_pe_plus>();
if (!optional_header_->load(stream)) {
clean();
return false;
Expand All @@ -228,13 +228,13 @@ class coffi : public coffi_strings,
}
else {
if (architecture_ == COFFI_ARCHITECTURE_NONE) {
optional_header_ = new optional_header_impl_pe;
optional_header_ = std::make_unique<optional_header_impl_pe>();
}
if (architecture_ == COFFI_ARCHITECTURE_CEVA) {
optional_header_ = new optional_header_impl_pe;
optional_header_ = std::make_unique<optional_header_impl_pe>();
}
if (architecture_ == COFFI_ARCHITECTURE_TI) {
optional_header_ = new optional_header_impl_ti;
optional_header_ = std::make_unique<optional_header_impl_ti>();
}
if (!optional_header_->load(stream)) {
clean();
Expand All @@ -244,19 +244,17 @@ class coffi : public coffi_strings,

if (architecture_ == COFFI_ARCHITECTURE_PE) {
if (optional_header_->get_magic() == OH_MAGIC_PE32PLUS) {
win_header_ = new win_header_impl<win_header_pe_plus>;
win_header_ = std::make_unique<win_header_impl<win_header_pe_plus>>();
}
else if (optional_header_->get_magic() == OH_MAGIC_PE32 ||
optional_header_->get_magic() == OH_MAGIC_PE32ROM) {
win_header_ = new win_header_impl<win_header_pe>;
win_header_ = std::make_unique<win_header_impl<win_header_pe>>();
}

if (win_header_) {
if (!win_header_->load(stream)) {
delete optional_header_;
optional_header_ = 0;
delete win_header_;
win_header_ = 0;
optional_header_.reset();
win_header_.reset();
clean();
return false;
}
Expand All @@ -271,12 +269,12 @@ class coffi : public coffi_strings,
}

std::streampos pos = stream.tellg();
if (!load_strings(stream, coff_header_)) {
if (!load_strings(stream, coff_header_.get())) {
clean();
return false;
}

if (!load_symbols(stream, coff_header_)) {
if (!load_symbols(stream, coff_header_.get())) {
clean();
return false;
}
Expand Down Expand Up @@ -357,17 +355,17 @@ class coffi : public coffi_strings,
architecture_ = architecture;

if (architecture_ == COFFI_ARCHITECTURE_PE) {
coff_header_ = new coff_header_impl;
coff_header_ = std::make_unique<coff_header_impl>();
coff_header_->set_machine(IMAGE_FILE_MACHINE_I386);
}

if (architecture_ == COFFI_ARCHITECTURE_CEVA) {
coff_header_ = new coff_header_impl;
coff_header_ = std::make_unique<coff_header_impl>();
coff_header_->set_machine(CEVA_MACHINE_XC4210_OBJ);
}

if (architecture_ == COFFI_ARCHITECTURE_TI) {
coff_header_ = new coff_header_impl_ti;
coff_header_ = std::make_unique<coff_header_impl_ti>();
coff_header_->set_target_id(TMS320C2800);
}
}
Expand All @@ -389,27 +387,27 @@ class coffi : public coffi_strings,
void create_optional_header(uint16_t magic = OH_MAGIC_PE32)
{
if (dos_header_) {
delete dos_header_;
dos_header_.reset();
}
if (optional_header_) {
delete optional_header_;
optional_header_.reset();
}
if (architecture_ == COFFI_ARCHITECTURE_PE) {
dos_header_ = new dos_header;
dos_header_ = std::make_unique<dos_header>();
if (magic == OH_MAGIC_PE32PLUS) {
optional_header_ = new optional_header_impl_pe_plus;
optional_header_ = std::make_unique<optional_header_impl_pe_plus>();
}
else {
optional_header_ = new optional_header_impl_pe;
optional_header_ = std::make_unique<optional_header_impl_pe>();
}
optional_header_->set_magic(magic);
create_win_header();
}
if (architecture_ == COFFI_ARCHITECTURE_CEVA) {
optional_header_ = new optional_header_impl_pe;
optional_header_ = std::make_unique<optional_header_impl_pe>();
}
if (architecture_ == COFFI_ARCHITECTURE_TI) {
optional_header_ = new optional_header_impl_ti;
optional_header_ = std::make_unique<optional_header_impl_ti>();
}
coff_header_->set_optional_header_size(narrow_cast<uint16_t>(
optional_header_->get_sizeof() + win_header_->get_sizeof() +
Expand All @@ -421,51 +419,51 @@ class coffi : public coffi_strings,
*
* @return nullptr if the MS-DOS header is not initialized (see create_optional_header()), or not loaded (see load()), or not relevant for the architecture.
*/
dos_header* get_msdos_header() { return dos_header_; }
dos_header* get_msdos_header() { return dos_header_.get(); }

//---------------------------------------------------------------------
/*! @copydoc get_msdos_header()
*/
const dos_header* get_msdos_header() const { return dos_header_; }
const dos_header* get_msdos_header() const { return dos_header_.get(); }

//---------------------------------------------------------------------
/*! @brief Returns the COFF header
*
* @return nullptr if the coffi object is not initialized (see create()), or not loaded (see load()).
*/
coff_header* get_header() { return coff_header_; }
coff_header* get_header() { return coff_header_.get(); }

//---------------------------------------------------------------------
/*! @copydoc get_header()
*/
const coff_header* get_header() const { return coff_header_; }
const coff_header* get_header() const { return coff_header_.get(); }

//---------------------------------------------------------------------
/*! @brief Returns the optional COFF header
*
* @return nullptr if the optional COFF header is not initialized (see create_optional_header()), or not loaded (see load()).
*/
optional_header* get_optional_header() { return optional_header_; }
optional_header* get_optional_header() { return optional_header_.get(); }

//---------------------------------------------------------------------
/*! @copydoc get_optional_header()
*/
const optional_header* get_optional_header() const
{
return optional_header_;
return optional_header_.get();
}

//---------------------------------------------------------------------
/*! @brief Returns the Windows NT header
*
* @return nullptr if the Windows NT header is not initialized (see create_optional_header()), or not loaded (see load()), or not relevant for the architecture.
*/
win_header* get_win_header() { return win_header_; }
win_header* get_win_header() { return win_header_.get(); }

//---------------------------------------------------------------------
/*! @copydoc get_win_header()
*/
const win_header* get_win_header() const { return win_header_; }
const win_header* get_win_header() const { return win_header_.get(); }

//---------------------------------------------------------------------
/*! @brief Returns a list of the COFF sections
Expand Down Expand Up @@ -598,23 +596,19 @@ class coffi : public coffi_strings,
void clean()
{
if (dos_header_) {
delete dos_header_;
dos_header_ = 0;
dos_header_.reset();
}

if (coff_header_) {
delete coff_header_;
coff_header_ = 0;
coff_header_.reset();
}

if (optional_header_) {
delete optional_header_;
optional_header_ = 0;
optional_header_.reset();
}

if (win_header_) {
delete win_header_;
win_header_ = 0;
win_header_.reset();
}

clean_unused_spaces();
Expand All @@ -631,14 +625,14 @@ class coffi : public coffi_strings,
void create_win_header()
{
if (win_header_) {
delete win_header_;
win_header_.reset();
}
if (optional_header_->get_magic() == OH_MAGIC_PE32PLUS) {
win_header_ = new win_header_impl<win_header_pe_plus>;
win_header_ = std::make_unique<win_header_impl<win_header_pe_plus>>();
}
else if (optional_header_->get_magic() == OH_MAGIC_PE32 ||
optional_header_->get_magic() == OH_MAGIC_PE32ROM) {
win_header_ = new win_header_impl<win_header_pe>;
win_header_ = std::make_unique<win_header_impl<win_header_pe>>();
}
}

Expand Down Expand Up @@ -1060,15 +1054,15 @@ class coffi : public coffi_strings,
};

//---------------------------------------------------------------------
coffi_architecture_t architecture_;
dos_header* dos_header_;
coff_header* coff_header_;
optional_header* optional_header_;
win_header* win_header_;
directories directories_;
sections sections_;
std::vector<unused_space> unused_spaces_;
std::vector<data_page> data_pages_;
coffi_architecture_t architecture_;
std::unique_ptr<dos_header> dos_header_;
std::unique_ptr<coff_header> coff_header_;
std::unique_ptr<optional_header> optional_header_;
std::unique_ptr<win_header> win_header_;
directories directories_;
sections sections_;
std::vector<unused_space> unused_spaces_;
std::vector<data_page> data_pages_;
};

} // namespace COFFI
Expand Down
27 changes: 13 additions & 14 deletions coffi/coffi_directory.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class directory
{
public:
//------------------------------------------------------------------------------
directory(uint32_t index) : data_{nullptr}, index_{index} {}
directory(uint32_t index) : data_{}, index_{index} {}

//------------------------------------------------------------------------------
//! Discards the copy constructor
Expand All @@ -71,7 +71,7 @@ class directory
uint32_t get_index() const { return index_; }

//------------------------------------------------------------------------------
const char* get_data() const { return data_; }
const char* get_data() const { return data_.get(); }

//------------------------------------------------------------------------------
void set_data(const char* data, uint32_t size)
Expand All @@ -87,13 +87,13 @@ class directory
return;
}

char* temp_buffer = new char[size];
std::unique_ptr<char[]> temp_buffer = std::make_unique<char[]>(size);
if (!temp_buffer) {
set_size(0);
return;
}
std::copy(data, data + size, temp_buffer);
data_ = temp_buffer;
std::copy(data, data + size, temp_buffer.get());
data_ = std::move(temp_buffer);
set_size(size);
}

Expand Down Expand Up @@ -126,13 +126,13 @@ class directory
return true;
}
if ((get_size() > 0) && (get_virtual_address() != 0)) {
char* temp_buffer = new char[get_size()];
std::unique_ptr<char[]> temp_buffer = std::make_unique<char[]>(get_size());
stream.seekg(get_virtual_address());
stream.read(temp_buffer, get_size());
stream.read(temp_buffer.get(), get_size());
if (stream.gcount() != static_cast<int>(get_size())) {
return false;
}
data_ = temp_buffer;
data_ = std::move(temp_buffer);
}
return true;
}
Expand All @@ -150,23 +150,22 @@ class directory
return;
}
if (data_ && get_size() > 0) {
stream.write(data_, get_size());
stream.write(data_.get(), get_size());
}
}

//------------------------------------------------------------------------------
void clean()
{
if (data_) {
delete[] data_;
data_ = nullptr;
data_.reset();
}
}

private:
image_data_directory header{};
const char* data_;
uint32_t index_;
image_data_directory header{};
std::unique_ptr<const char[]> data_;
uint32_t index_;
};

/*! @brief List of image data directories
Expand Down
Loading

0 comments on commit 7878943

Please sign in to comment.