15168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju/*
25168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju * Copyright (C) 2018 The Android Open Source Project
35168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju *
45168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju * Licensed under the Apache License, Version 2.0 (the "License");
55168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju * you may not use this file except in compliance with the License.
65168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju * You may obtain a copy of the License at
75168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju *
85168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju *      http://www.apache.org/licenses/LICENSE-2.0
95168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju *
105168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju * Unless required by applicable law or agreed to in writing, software
115168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju * distributed under the License is distributed on an "AS IS" BASIS,
125168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju * See the License for the specific language governing permissions and
145168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju * limitations under the License.
155168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju */
165168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju
175168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju#include <stdio.h>
185168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju#include <stdlib.h>
195168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju#include <fstream>
205168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju
215168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju#include "ufdt_test_overlay.h"
225168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju
235168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsarajuextern "C" {
245168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju
255168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju#include "ufdt_overlay.h"
265168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju#include "libufdt_sysdeps.h"
275168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju
285168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju}
295168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju
305168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsarajusize_t read_file_to_buf(const char *filename, char** buf) {
315168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju    size_t size = 0;
325168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju    std::ifstream file(filename, std::ios::binary | std::ios::in);
335168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju
345168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju    if (!file) {
355168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju        return size;
365168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju    }
375168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju
385168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju    file.seekg(0, file.end);
395168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju    size = file.tellg();
405168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju    file.seekg(0, std::ios::beg);
415168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju
425168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju    *buf = new char[size];
435168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju    file.read(*buf, size);
445168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju    return size;
455168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju}
465168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju
475168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsarajuint verify_overlay_files(const char *final_filename,
484c7735ac0173b71aceb489470fca15b56e64c4d4Hridya Valsaraju                         char** overlay_filenames, size_t overlay_count) {
494c7735ac0173b71aceb489470fca15b56e64c4d4Hridya Valsaraju    char* final_buf = nullptr;
504c7735ac0173b71aceb489470fca15b56e64c4d4Hridya Valsaraju    void** overlay_buf_array = new void*[overlay_count];
515168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju    struct fdt_header *blob = nullptr;
525168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju    int result = 1;
535168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju    size_t final_size = 0, overlay_size = 0;
545168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju
555168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju    final_size = read_file_to_buf(final_filename, &final_buf);
565168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju    if (final_size == 0) {
575168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju        fprintf(stderr, "Cannot load final DTB: %s \n", final_filename);
585168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju        goto end;
595168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju    }
605168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju
614c7735ac0173b71aceb489470fca15b56e64c4d4Hridya Valsaraju    for (size_t i = 0; i < overlay_count; i++) {
624c7735ac0173b71aceb489470fca15b56e64c4d4Hridya Valsaraju        overlay_size = read_file_to_buf(overlay_filenames[i],
634c7735ac0173b71aceb489470fca15b56e64c4d4Hridya Valsaraju                                        reinterpret_cast<char**>(&overlay_buf_array[i]));
644c7735ac0173b71aceb489470fca15b56e64c4d4Hridya Valsaraju        if (overlay_size == 0) {
654c7735ac0173b71aceb489470fca15b56e64c4d4Hridya Valsaraju            fprintf(stderr, "Cannot load DTB Overlay: %s\n", overlay_filenames[i]);
664c7735ac0173b71aceb489470fca15b56e64c4d4Hridya Valsaraju            goto end;
674c7735ac0173b71aceb489470fca15b56e64c4d4Hridya Valsaraju        }
685168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju    }
695168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju
705168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju    blob = ufdt_install_blob(final_buf, final_size);
715168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju    if (!blob) {
725168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju        fprintf(stderr, "ufdt_install_blob() returns null\n");
735168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju        goto end;
745168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju    }
755168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju
764c7735ac0173b71aceb489470fca15b56e64c4d4Hridya Valsaraju    result = ufdt_verify_dtbo(blob, final_size, overlay_buf_array, overlay_count);
775168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju
785168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju    if (result != 0) {
794c7735ac0173b71aceb489470fca15b56e64c4d4Hridya Valsaraju        fprintf(stderr, "bad overlay error");
805168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju    }
815168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju
825168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsarajuend:
835168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju    // Do not dto_free(blob) - it's the same as final_buf.
844c7735ac0173b71aceb489470fca15b56e64c4d4Hridya Valsaraju    for (size_t i = 0; i < overlay_count; i++) {
854c7735ac0173b71aceb489470fca15b56e64c4d4Hridya Valsaraju        if (overlay_buf_array[i]) dto_free(overlay_buf_array[i]);
864c7735ac0173b71aceb489470fca15b56e64c4d4Hridya Valsaraju    }
874c7735ac0173b71aceb489470fca15b56e64c4d4Hridya Valsaraju    delete[] overlay_buf_array;
884c7735ac0173b71aceb489470fca15b56e64c4d4Hridya Valsaraju
895168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju    if (final_buf) dto_free(final_buf);
905168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju
915168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju    return result;
925168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju}
935168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju
945168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsarajuint main(int argc, char **argv) {
954c7735ac0173b71aceb489470fca15b56e64c4d4Hridya Valsaraju    if (argc < 3) {
964c7735ac0173b71aceb489470fca15b56e64c4d4Hridya Valsaraju        fprintf(stderr, "Usage: %s <final_file> <overlay_file1> <overlay_file2> ..\n", argv[0]);
974c7735ac0173b71aceb489470fca15b56e64c4d4Hridya Valsaraju        return 1;
984c7735ac0173b71aceb489470fca15b56e64c4d4Hridya Valsaraju    }
994c7735ac0173b71aceb489470fca15b56e64c4d4Hridya Valsaraju
1004c7735ac0173b71aceb489470fca15b56e64c4d4Hridya Valsaraju    const char *final_file = argv[1];
1014c7735ac0173b71aceb489470fca15b56e64c4d4Hridya Valsaraju    char** overlay_file_names = new char*[argc - 2];
1025168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju
1034c7735ac0173b71aceb489470fca15b56e64c4d4Hridya Valsaraju    for(int argv_idx = 2; argv_idx < argc; argv_idx++) {
1044c7735ac0173b71aceb489470fca15b56e64c4d4Hridya Valsaraju        overlay_file_names[argv_idx - 2] = argv[argv_idx];
1054c7735ac0173b71aceb489470fca15b56e64c4d4Hridya Valsaraju    }
1064c7735ac0173b71aceb489470fca15b56e64c4d4Hridya Valsaraju    int ret = verify_overlay_files(final_file, overlay_file_names, argc - 2);
1075168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju
1084c7735ac0173b71aceb489470fca15b56e64c4d4Hridya Valsaraju    return ret == 0 ? ret : 1;
1095168cab4cb068dc964e6354167bc857a0e948ff7Hridya Valsaraju}
110